We use a handful of security mechanisms to ensure that your requests are secure. You can find information on how to make a secure authenticated request below.

In order to make an authenticated request you'll need to pass a couple of values through the HTTP headers with your request:

HTTP Header FieldDescription
X-Api-KeyYour Wyre API key. Your key can be found at https://dash.sendwyre.com/settings/api-keys
X-Api-SignatureA signature used to verify the request was sent by the account holder. See Calculating the request signature.

Additionally, you should include a GET parameter named timestamp which is the current time in millisecond epoch format. We use this timestamp to help protect against replay attacks.

Calculating the request signature

Calculating the X-Api-Signature field is a two step process

  1. Concatenate the request URL with the body of the HTTP request into a UTF-8 String. Use an empty string for the HTTP body in GET requests.
  2. Compute the signature using HMAC with SHA-256 and your API Secret Key.

If you are sending a GET request you would sign the following:

https://api.sendwyre.com/v2/rates?timestamp=1426252182534

If you are making a POST request you would sign the following:

https://api.sendwyre.com/v2/transfers?timestamp=1426252182534

Note: You must send the request body exactly as you sign it, whitespace and all. The server calculates the signature based on exactly what's in the request body.

Examples

Below are example implementations of authentication in a couple of different languages.
<?php function make_authenticated_request($endpoint, $method, $body) { $url = 'https://api.sendwyre.com'; $api_key = "bh405n7stsuo5ut30iftrsl71b4iqjnv"; $secret_key = "a19cvrchgja82urvn47kirrlrrb7stgg"; $timestamp = floor(microtime(true)*1000); $request_url = $url . $endpoint; if(strpos($request_url,"?")) $request_url .= '&timestamp=' . $timestamp; else $request_url .= '?timestamp=' . $timestamp; if(!empty($body)) $body = json_encode($body, JSON_FORCE_OBJECT); else $body = ''; $headers = array( "Content-Type: application/json", "X-Api-Key: ". $api_key, "X-Api-Signature: ". calc_auth_sig_hash($secret_key, $request_url . $body), "X-Api-Version: 2" ); $curl = curl_init(); if($method=="POST"){ $options = array( CURLOPT_URL => $request_url, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_RETURNTRANSFER => true); }else { $options = array( CURLOPT_URL => $request_url, CURLOPT_RETURNTRANSFER => true); } curl_setopt_array($curl, $options); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($curl); curl_close($curl); var_dump($result); return json_decode($result, true); } function calc_auth_sig_hash($seckey, $val) { $hash = hash_hmac('sha256', $val, $seckey); return $hash; } echo make_authenticated_request("/account", "GET", array()); $transfer = array( "sourceCurrency"=>"USD", "dest"=>"sam@sendwyre.com", "destAmount"=> 55.05, "destCurrency"=>"EUR", "message"=> "buy sam pizza" ); echo make_authenticated_request("/transfers", "POST", $transfer); ?>
using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Security.Cryptography; using System.Text; using System.Linq; using Newtonsoft.Json.Linq; using Newtonsoft.Json; namespace testauthwyre { class MainClass { public static void Main(string[] args) { WyreApi wyre = new WyreApi(); HttpWebResponse accountResponse = wyre.Get("/account"); Console.WriteLine(GetResponseBody(accountResponse)); Dictionary<string, object> body = new Dictionary<string, object>(); body.Add("sourceCurrency", "USD"); body.Add("sourceAmount", "10"); body.Add("dest", "test@sendwyre.com"); HttpWebResponse transferResponse = wyre.Post("/transfers", body); Console.WriteLine(GetResponseBody(transferResponse)); } private static string GetResponseBody(HttpWebResponse response) { return JObject.Parse(new StreamReader(response.GetResponseStream()).ReadToEnd()).ToString(Formatting.Indented); } } public class WyreApi { private const String domain = "https://api.sendwyre.com"; private const String apiKey = "xxx"; private const String secKey = "xxx"; public HttpWebResponse Get(string path) { return Get(path, new Dictionary<string, object>()); } public HttpWebResponse Get(string path, Dictionary<string, object> queryParams) { return Request("GET", path, queryParams); } public HttpWebResponse Post(string path, Dictionary<string, object> body) { return Request("POST", path, body); } private HttpWebResponse Request(string method, string path, Dictionary<string, object> body) { Dictionary<string, object> queryParams = new Dictionary<string, object>(); if (method.Equals("GET")) queryParams = body; queryParams.Add("timestamp", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()); string queryString = queryParams.Aggregate("", (previous, current) => previous + "&" + current.Key + "=" + current.Value).Remove(0, 1); string url = domain + path + "?" + queryString; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = method; request.ContentType = "application/json"; request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; if (!method.Equals("GET")) { url += JsonConvert.SerializeObject(body); using (StreamWriter writer = new StreamWriter(request.GetRequestStream())) writer.Write(JsonConvert.SerializeObject(body)); } request.Headers["X-Api-Key"] = apiKey; request.Headers["X-Api-Signature"] = CalcAuthSigHash(secKey, url); request.Headers["X-Api-Version"] = "2"; try { return (HttpWebResponse)request.GetResponse(); } catch(WebException e) { string msg = new StreamReader(e.Response.GetResponseStream()).ReadToEnd(); Console.WriteLine(msg); throw new SystemException(msg); } } private byte[] GetBytes(string str) { return Encoding.UTF8.GetBytes(str); } private string GetString(byte[] bytes) { return BitConverter.ToString(bytes); } private String CalcAuthSigHash(string key, string value) { HMACSHA256 hmac = new HMACSHA256(GetBytes(key)); string hash = GetString(hmac.ComputeHash(GetBytes(value))).Replace("-", ""); return hash; } } }
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.Integer; import java.lang.String; import java.lang.StringBuffer; import java.net.HttpURLConnection; import java.net.URL; public class TestAuth { public static void main(String[] args) { String apiKey = "PUT YOUR API KEY HERE"; String secretKey = "PUT YOUR SECRET KEY HERE"; String url = "https://api.sendwyre.com/account"; String method = "GET"; String data = ""; String result = executeWyreRequest(url, "", method, apiKey, secretKey); System.out.println(result); url = "https://api.sendwyre.com/transfers"; method = "POST"; data = "{" + " \"dest\": \"sam@sendwyre.com\"," + " \"destCurrency\": \"USD\"," + " \"sourceCurrency\" : \"BTC\"," + " \"sourceAmount\" : \"1\"," + " \"message\": \"$1 worth of bitcoin!\"" + "}"; result = executeWyreRequest(url, data, method, apiKey, secretKey); System.out.println(result); } public static String executeWyreRequest(String targetURL, String requestBody, String method, String apiKey, String secretKey) { URL url; HttpURLConnection connection = null; try { targetURL += ((targetURL.indexOf("?")>0)?"&":"?") + "timestamp=" + System.currentTimeMillis(); //Create connection url = new URL(targetURL); connection = (HttpURLConnection)url.openConnection(); connection.setRequestMethod(method); System.out.println(connection.getRequestMethod()); connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Content-Length", Integer.toString(requestBody.getBytes().length)); //Specify API v2 connection.setRequestProperty("X-Api-Version","2"); // Provide API key and signature connection.setRequestProperty("X-Api-Key", apiKey); connection.setRequestProperty("X-Api-Signature",computeSignature(secretKey,targetURL,requestBody)); //Send request if(method.equals("POST")) { connection.setDoOutput(true); connection.setRequestMethod(method); DataOutputStream wr = new DataOutputStream( connection.getOutputStream()); wr.write(requestBody.getBytes("UTF-8")); wr.flush(); wr.close(); } //Get Response InputStream is; if (connection.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) { is = connection.getInputStream(); } else { is = connection.getErrorStream(); } BufferedReader rd = new BufferedReader(new InputStreamReader(is)); String line; StringBuffer response = new StringBuffer(); while((line = rd.readLine()) != null) { response.append(line); response.append('\r'); } rd.close(); return response.toString(); } catch (Exception e) { e.printStackTrace(); return null; } finally { if(connection != null) { connection.disconnect(); } } } public static String computeSignature(String secretKey, String url, String reqData) { String data = url + reqData; System.out.println(data); try { Mac sha256Hmac = Mac.getInstance("HmacSHA256"); SecretKeySpec key = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256"); sha256Hmac.init(key); byte[] macData = sha256Hmac.doFinal(data.getBytes("UTF-8")); String result = ""; for (final byte element : macData){ result += Integer.toString((element & 0xff) + 0x100, 16).substring(1); } return result; } catch (Exception e) { e.printStackTrace(); return ""; } } }
require 'uri' require 'net/http' require 'digest/hmac' require 'json' class WyreApi ACCOUNT_ID = 'ue5hsnusf8gene87asdf4es23bt9d7ak' API_KEY = '9idihi38o18mrm1234ipa1k9ooiifgts' SEC_KEY = '5e3kcoogptge6s5fh2qwertyb6g368dm' API_URL = 'https://api.sendwyre.com' def create_transfer options api_post '/transfers', options end private def api_post path, post_data = {} params = { 'timestamp' => (Time.now.to_i * 1000).to_s } url = API_URL + path + '?' + URI.encode_www_form(params) headers = { 'X-Api-Key' => API_KEY, 'X-Api-Signature' => calc_auth_sig_hash(url + post_data.to_json.to_s), 'X-Api-Version' => '2' } uri = URI API_URL Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http| http.request_post(url, post_data.to_json.to_s, headers) do |res| response = JSON.parse res.body raise response['message'] if res.code != '200' return response end end end def calc_auth_sig_hash url_body return Digest::HMAC.hexdigest url_body, SEC_KEY, Digest::SHA256 end end api = WyreApi.new api.create_transfer({'sourceAmount'=>50,'sourceCurrency'=>'USD','dest'=>'sam@sendwyre.com', 'destCurrency'=>'EUR', 'message'=>'buy sam pizza')
#dependencies: #python3 #pip3 install requests import json import hmac import time from requests import request class MassPay_API(object): def __init__(self, account_id, api_version, api_key, api_secret): self.account_id = account_id self.api_url = 'https://api.sendwyre.com/{}'.format(api_version) self.api_version = api_version self.api_key = api_key self.api_secret = api_secret #authentication decorator. May raise ValueError if no json content is returned def authenticate_request(func): def wrap(self, *args, **kwargs): url, method, body = func(self, *args, **kwargs) params = {} timestamp = int(time.time() * 1000) url += '?timestamp={}'.format(timestamp) bodyJson = json.dumps(body) if body != '' else '' headers = {} headers['Content-Type'] = 'application/json' headers['X-Api-Version'] = self.api_version headers['X-Api-Key'] = self.api_key headers['X-Api-Signature'] = hmac.new(self.api_secret.encode('utf-8'), (url + bodyJson).encode('utf-8'), 'SHA256').hexdigest() print(headers['X-Api-Signature']) resp = request(method=method, url=url, params=params, data=(json.dumps(body) if body != '' else None), json=None, headers=headers) if resp.text is not None: #Wyre will always try to give an err body return resp.status_code, resp.json() return 404, {} return wrap @authenticate_request def retrieve_exchange_rates(self): url = self.api_url + '/rates' method = 'GET' body = '' return url, method, body @authenticate_request def retrieve_account(self): url = self.api_url + '/account' method = 'GET' body = '' return url, method, body @authenticate_request def create_transfer(self, sourceAmount, sourceCurrency, destAmount, destCurrency, destAddress, message, autoConfirm): url = self.api_url + '/transfers' method = 'POST' #ONLY use either sourceAmount or destAmount, see documentation body = {'sourceCurrency':sourceCurrency, 'dest':destAddress, 'destCurrency':destCurrency, 'message':message} if sourceAmount: body["sourceAmount"] = sourceAmount elif destAmount: body["destAmount"] = destAmount if autoConfirm: body['autoConfirm'] = True return url, method, body @authenticate_request def confirm_transfer(self, transfer_id): url = self.api_url + '/transfer/{}/confirm'.format(transfer_id) method = 'POST' body = '' return url, method, body @authenticate_request def status_transfer(self, transfer_id): url = self.api_url + '/transfer/{}'.format(transfer_id) method = 'GET' body = '' return url, method, body #USAGE Example account_id = "YOUR_ACCOUNT_ID_HERE" #optional api_key = "YOUR_API_KEY_HERE" secret_key = "YOUR_SECRET_KEY_HERE" api_version = "2" #create Wyre API object Wyre = Pay_API(account_id, api_version, api_key, secret_key) #get account info http_code, account = Wyre.retrieve_account() print(account) #get exchange rate info http_code, rate_result = Wyre.retrieve_exchange_rates() print(rate_result) #BTC to CNY rate btc_cny = rate_result.get("BTCCNY") #amount of source (withdrawal) BTC we want to sent to Euro amount = 50 #calculate destination (deposit) amount in CNY final_amount = amount * btc_cny #example bank transfer bank_transfer = { "paymentMethodType":"INTERNATIONAL_TRANSFER", "country": "CN", "currency": "CNY", "nameOnAccount": "成龍", "accountNumber": "1234dinosaur", "bankName": "ζ‹›ε•†ι“Άθ‘Œ", "accountType": "金卑", "branchCode": "ε…‰εŽθ·―ζ”―θ‘Œ", "accountHolderEmail": "banana@phone.com", "accountHolderPhoneNumber": "+14102239203", "swift": "DEUTUS00000", "beneficiaryType": "INDIVIDUAL", "priority":"HIGH" } #don't actually run this unless you really want to give Sam pizza http_code, transfer_result = Wyre.create_transfer( amount, "BTC", None, #final_amount "CNY", bank_transfer, #may also be an email or SRN "sending Wyre developers pizza money", False) print(transfer_result) tx_id = transfer_result['id'] http_code, status = Wyre.status_transfer('AWEvg0lZhq6qpXX') print(status)