Step 4: First API Call

When testing the authentication first try with a simple GET request such as Get Crypto Currencies or Get Payment Methods.

Sample Code

Here is some sample code around how to call the API including HMAC authentication. Key things to note when building your integration:

  • The data passed to the HMAC algorithm are separated by new lines
  • The JSON payload for POST requests should contain no whitespace
  • The nonce should be a unix timestamp which is generated for every request
  • When generating the data for the HMAC algorithm include the query string
function generateHmac(data, nonce) {
   ...
}

function sendGetRequest(query) {
const hostname = 'api.banxa-sandbox.com';
const nonce = Date.now();
const method = 'GET'
let data = method + "\n" + query + "\n" + nonce;

const hmac = generateHmac(data, nonce);
const https = require('https')
const options = {
    hostname: hostname,
    path: query,
    method: method,
    headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${hmac}`
    }
}

const req = https.get(options, (res) => {
    console.log(`STATUS: ${res.statusCode}`);
    console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
    res.setEncoding('utf8');
    res.on('data', (chunk) => {
      console.log(`BODY: ${chunk}`);
    });
    res.on('end', () => {
      console.log('No more data in response.');
    });
  });
  
  req.on('error', (e) => {
    console.error(`problem with request: ${e.message}`);
  });
}
import requests
import time
import hmac

url = 'https://api.banxa-sandbox.com'
key = '[YOUR_MERCHANT_KEY]'
secret = b'[YOUR_MERCHANT_SECRET]'

def generateHmac(payload, nonce):
    hmacCode = hmac.digest(secret, payload.encode('utf8'), 'SHA256')

    print(payload)
    print(hmacCode.hex())

    return key + ':' + hmacCode.hex() + ':' + str(nonce)

def sendGetRequest(query):
    nonce = int(time.time())

    data = 'GET\n' + query + '\n' + str(nonce)

    authHeader = generateHmac(data, nonce)

    response = requests.get(url + query,
        headers = {
                'Authorization': 'Bearer ' + authHeader,
                'Content-Type': 'application/json'
        })

    print(response.content)

def sendPostRequest(query, payload):
    nonce = int(time.time())

    data = 'POST\n' + query + '\n' + str(nonce) + '\n' + payload

    authHeader = generateHmac(data, nonce)

    response = requests.post(url + query,
        data = payload,
        headers = {
                'Authorization': 'Bearer ' + authHeader,
                'Content-Type': 'application/json'
        })

    print(response.content)

sendGetRequest('/api/fiats')

print('----')

sendPostRequest('/api/orders', '{"account_reference":"test01","source":"USD","target":"BTC","source_amount":"100","return_url_on_success":"test.com","wallet_address":"[VALID_WALLET_ADDRESS]"}')
package com.banxa;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Formatter;

public class BanxaService {
    private static final String BANXA_URL = "https://api.banxa-sandbox.com";
    private static final String KEY = "[YOUR_MERCHANT_KEY]";
    private static final String SECRET = "[YOUR_MERCHANT_SECRET]";

    public static void main(String[] args) throws Exception {
        BanxaService banxaService = new BanxaService();
        banxaService.sendGetRequest("/api/coins");

        banxaService.sendPostRequest("/api/orders", "{" +
                "\"account_reference\":\"test01\"," +
                "\"source\":\"USD\"," +
                "\"target\":\"BTC\"," +
                "\"source_amount\":\"100\"," +
                "\"return_url_on_success\":\"test.com\"," +
                "\"wallet_address\":\"[VALID_WALLET_ADDRESS]\""+
                "}");
    }

    private void sendGetRequest(String query) throws Exception {
        String hmac = getHmac("GET", query, null);

        HttpClient httpClient = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.banxa-dev.com" + query))
                .timeout(Duration.ofSeconds(10))
                .header("Authorization", "Bearer " + hmac)
                .header("content-type", "application/json")
                .GET()
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() == 200) {
            System.out.println("OK");
        } else {
            System.out.println("Failed: " + response.statusCode());
        }
    }

    private void sendPostRequest(String query, String payload) throws Exception {
        String hmac = getHmac("POST", query, payload);

        HttpClient httpClient = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(BANXA_URL + query))
                .timeout(Duration.ofSeconds(10))
                .header("Authorization", "Bearer " + hmac)
                .header("content-type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(payload))
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() == 200) {
            System.out.println("OK");
        } else {
            System.out.println("Failed: " + response.statusCode());
        }
    }

    public String getHmac(String method, String query, String payload) throws Exception {
        String nonce = String.valueOf(System.currentTimeMillis());

        String data = method + "\n" +
                query + "\n" +
                nonce;

        if (payload != null) {
            data += "\n" + payload;
        }

        SecretKeySpec signingKey = new SecretKeySpec(SECRET.getBytes(), "HmacSHA256");
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(signingKey);
        return KEY + ":" + toHexString(mac.doFinal(data.getBytes())) + ":" + nonce;
    }

    private String toHexString(byte[] bytes) {
        Formatter formatter = new Formatter();
        for (byte b : bytes) {
            formatter.format("%02x", b);
        }
        return formatter.toString();
    }
}
import CryptoKit
import Foundation

let hostname = "https://api.banxa-sandbox.com/"
let key = "[YOUR_MERCHANT_KEY]"
let secret = "[YOUR_MERCHANT_SECRET]".data(using: .utf8)!
let secretKey = SymmetricKey(data: secret)

public func generateHmac(payload: String, nonce: String) -> String {
    ...
}


public func getRequest(query: String) {
    let method = "GET"
    let hmac = generateHmac(method: method, query: query)
    
    var request = URLRequest(url: URL(string: hostname + query)!)
    
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("Bearer " + hmac, forHTTPHeaderField: "Authorization")
    
    let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
        guard error == nil else {
            return
        }
        
        guard let data = data else {
            return
        }
        
        do {
            //create json object from data
            if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                print (json)
            }
        } catch let error {
            print(error.localizedDescription)
        }
    })
    task.resume()
}

getRequest(query: "api/payment-methods?source=USD")
require 'rest-client'
require 'openssl'

def generate_hmac(time, query, body, method = 'POST')
  ...
end

def request_env_url(resource)
  "https://api.banxa-sandbox.com#{query}"
end

def get_request(query)
  response = RestClient.get(request_env_url(query), signed_header(query, payload, 'GET'))
  JSON.parse(response.body)
end

def signed_header(query, body = nil, method = 'POST', content_type = 'application/json')
  epoch_time = Time.now.to_i
  access_signature = generate_hmac(epoch_time, resource, body, method)
  {
    "Authorization": "Bearer #{access_signature.encode('UTF-8').to_s}",
    "Accept": 'application/json',
    "Content-Type": content_type.to_s
  }
end