通过本教程可以快速上手Wyre MassPay API.
什么是MassPay?

客户可以使用MassPay在不同货币间转账。如果您有跨国转账汇款的需求,MassPay是您的首选。

目录:

  1. 开设Wyre账户
  2. 发送API请求
  3. 创建第一笔转账请求
  4. 转账示例
  5. 代码示例
  6. 相关链接和联系方式

1. 开设Wyre账户

首先,如果您没有账户,需要创建一个账户。这个过程中需要核对email和手机号。
开始转账前您需要有以下的信息:

  • API Key
  • SECRET Key
  • ACCOUNT ID

这些信息可以在登陆后的Your Account | API Keys里找到。
当生成一个API key后,页面显示如下图。

494

最后还需要AccountID。可以从key的details链接里找到。

667

注意
请不要包含"account:"字符串。
例如:account:pm9ddj8jr8rrq53fsk9v4bfhunieu72t应为pm9ddj8jr8rrq53fsk9v4bfhunieu72t

2. 发送API请求

Wyre API文档链接为https://api.sendwyre.com/v2/。返回格式为JSON。
Wyre利用如下的HTTP头字段作为安全措施。

头字段描述
X-Api-Key您的Wyre API key
X-Api-Signature用secret key计算得到的密钥散列消息认证码

计算您的密钥散列消息认证码的步骤如下(代码示例在页底):

  1. 在请求URL后加上毫秒时间戳。例如为了得到账户细节,请求URL为https://api.sendwyre.com/v2/account?timestamp=1426252182534
  2. 将请求的URL和HTTP请求内容合并成一个UTF-8字符串。GET请求内容为一个空字符串。
  3. 用SHA-256和您的API Secret Key计算签名。
    以下是Wyre MassPay API节点。点击名称链接进入相应文档。
名称API节点HTTP方法描述
账户详情https://api.sendwyre.com/v2/accountGET账户详情包括联系方式,所有货币的结余,相关授权和支付方式。
实时价格https://api.sendwyre.com/v2/ratesGET不同交易所的比特币价格。
创建转账https://api.sendwyre.com/v2/transfersPOST创建两种货币间的转账。目的地可以是email地址,比特币钱包地址或者银行账户。可以开启自动确认功能,但并不推荐。
转账确认https://api.sendwyre.com/v2/transfer/:transferId/confirmPOST转账只会在您确认所有细节之后的30秒内执行。
转账状态https://api.sendwyre.com/v2/transfer/:transferIdGET如果您不想用callbackUrl,您可以通过本API获得订单状态。不同订单状态种类在这里

创建第一个转账请求

一个转账请求是一个包含最多7个字段的JSON POST请求。

  • sourceAmount - 只需要选择 sourceAmount 或者 destAmount中一个。sourceAmount是从主账户中扣除的用来转账的金额。这种情况下您可以指定从账户中扣除的金额,入账金额将由交易费用和汇率确定。
  • sourceCurrency - 转出货币代码ISO 3166-1 alpha-3
  • dest - 转账地址。可以是email地址,电话号码,blockchain地址,或银行账户。
  • destAmount - 只需要选择 sourceAmount 或者 destAmount中一个。destAmount是将被转入目标地址的金额。sourceAmount可以由destAmount,交易费用和汇率计算出。
  • destCurrency - 转入货币代码。可以和转出货币代码不同。如果不同则汇率会被自动计算。
  • callbackUrl - 可选,Wyre返回转账状态的Url。
  • autoConfirm - 可选,默认自动确认转账的参数。不推荐。

以下例子将巴西雷亚尔转换为美元并发送到我们工程师的银行账户。

{
  "dest": {
    "paymentMethodType":"INTERNATIONAL_TRANSFER",
    "country": "US",
    "currency": "USD",
    "firstNameOnAccount": "Sam",
    "lastNameOnAccount":"Schlachter",
    "accountNumber": "1234dinosaur",
    "routingNumber": "0000000000",
    "accountType": "savings",
    "bankName": "Bank of 'murrrica",
    "bankStreet": "112 Brannan St",
    "bankCity": "San Francisco",
    "bankPostal": "94108",
    "accountHolderPhoneNumber": "+14102239203",
    "beneficiaryType": "INDIVIDUAL",
    "priority":"HIGH"
  },
  "sourceCurrency": "BRL",
  "destCurrency": "USD",
  "destAmount": 10,
  "message":"Here's your $10!"
}

返回值类似。最重要的返回值是id字段。我们用这个值确认转账并获取转账状态。

如果转账金额和汇率满足我们的要求,我们需要点击[转账确认](或者用自动确认功能)来确认转账。

最后一步是从转账状态获取转账的状态--完成过期,或者失败。或者你可以在callbackUrl字段填入一个URL。Wyre会将包含订单状态的HTTP POST请求发送到该URL。

以下是包含银行账户的转账示例。

转账示例

美国 USA 🇺🇸 → 🇧🇷 巴西 BRAZIL

{
  "dest": {
    "paymentMethodType":"INTERNATIONAL_TRANSFER",
    "country": "BR",
    "currency": "BRL",
    "firstNameOnAccount": "Robert",
    "lastNameOnAccount": "Baratheon",
    "accountNumber": "1234dinosaur",
    "bankName": "Mordor Credit Union",
    "cpfCnpj": "943759353",
    "accountType": "poupanca",
    "branchCode": "Artichoke",
    "accountHolderEmail": "[email protected]",
    "accountHolderPhoneNumber": "+14102239203",
    "swift": "DEUTUS00000",
    "beneficiaryType": "INDIVIDUAL",
    "priority":"HIGH"
  },
  "sourceCurrency": "USD",
  "destCurrency": "BRL",
  "destAmount": 10,
  "message":"A Lannister always pays his debts "
}

巴西 BRAZIL 🇧🇷 → 🇺🇸 美国 USA

{
  "dest": {
    "paymentMethodType":"INTERNATIONAL_TRANSFER",
    "country": "US",
    "currency": "USD",
    "beneficiaryType": "INDIVIDUAL",
    "beneficiaryAddress": "112 Brannan St",
    "beneficiaryAddress2": "", //Optional
    "beneficiaryCity": "San Francisco",
    "beneficiaryState": "CA",
    "beneficiaryPostal": "94108",
    "beneficiaryPhoneNumber": "+14102239203",
    "beneficiaryDobDay": "15",
    "beneficiaryDobMonth":"12",
    "beneficiaryDobYear":"1989",
    "paymentType" : "LOCAL_BANK_WIRE", // LOCAL_BANK_WIRE or ACH
    "firstNameOnAccount": "Billy-Bob",
    "lastNameOnAccount":"Jones",
    "accountNumber": "0000000000000",
    "routingNumber": "0000000000",
    "accountType": "CHECKING", //CHECKING or SAVINGS
    "bankName": "Bank of America"
  },
  "sourceCurrency": "BRL",
  "destCurrency": "USD",
  "destAmount": 10,
  "message":"USD Personal example"
}

美国 USA 🇺🇸 → 🇨🇳 中国 CHINA

{
  "dest": {
    "paymentMethodType":"INTERNATIONAL_TRANSFER",
    "country": "CN",
    "currency": "CNY",
    "nameOnAccount": "成龍",
    "accountNumber": "1234dinosaur",
    "bankName": "招商银行",
    "accountType": "金卡",
    "branchCode": "光华路支行",
    "accountHolderEmail": "[email protected]",
    "accountHolderPhoneNumber": "+14102239203",
    "swift": "DEUTUS00000",
    "beneficiaryType": "INDIVIDUAL",
    "priority":"HIGH"
  },
  "sourceCurrency": "USD",
  "destCurrency": "CNY",
  "destAmount": 10,
  "message":""
}

代码示例

你可以把自己的API Key,API Secret Key和Account ID放入以下脚本中,调整转账参数,即刻开始用MassPay转账!

#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, destination, message, autoConfirm):
        url = self.api_url + '/transfers'
        method = 'POST'
        #ONLY use either sourceAmount or destAmount, see documentation
        body = {'sourceCurrency':sourceCurrency,
                'dest':destination, #email, wallet, or bank transfer dict
                '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 MassPay API object
wyre = MassPay_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 dictionary that we will pass in as the destination
bank_transfer =   {
                "paymentMethodType":"INTERNATIONAL_TRANSFER",
                "country": "CN",
                "currency": "CNY",
                "nameOnAccount": "成龍",
                "accountNumber": "1234dinosaur",
                "bankName": "招商银行",
                "accountType": "金卡",
                "branchCode": "光华路支行",
                "accountHolderEmail": "[email protected]",
                "accountHolderPhoneNumber": "+14102239203",
                "swift": "DEUTUS00000",
                "beneficiaryType": "INDIVIDUAL",
                "priority":"HIGH"
                }

#send transfer and print result
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'] #grab our transfer id

#confirm transfer
http_code, confirmation = wyre.confirm_transfer(tx_id)
print(confirmation)

#check status
http_code, status = wyre.status_transfer(tx_id)
print(status)
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'=>'[email protected]', 'destCurrency'=>'EUR', 'message'=>'buy sam pizza')
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 Main {
  public static void main(String[] args) {
    String apiKey = "fll36l3t35udalcqlh4ng6bm4qpbgher";
    String secretKey = "tr3epinbk3maist0n3ijk18bm6dikrq6";

    //retrieve account details and balance
    String url = "https://api.sendwyre.com/account";
    String method = "GET";
    String data = "";

    String result = executewyreRequest(url, "", method, apiKey, secretKey);
    System.out.println(result);

    //example transfer
    url = "https://api.sendwyre.com/transfers";
    method = "POST";
    data = "{" +
        "  \"dest\": \"[email protected]\"," +
        "  \"destCurrency\": \"BTC\"," +
        "  \"sourceCurrency\" : \"USD\"," +
        "  \"sourceAmount\" : \"50\"," +
        "  \"message\": \"$50 worth of bitcoin! Food please!\"" +
        "}";
    result = excutewyreRequest(url, data, method, apiKey, secretKey);

    System.out.println(result);
  }

  public static String excutewyreRequest(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.writeBytes(requestBody);
        wr.flush();
        wr.close();
      }

      //Get Response
      InputStream is = null;
      if (connection.getResponseCode() >= 400) {
        is = connection.getErrorStream();
      }  
      else {
        is = connection.getInputStream();
      }
      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());

      String result = "";
      for (final byte element : macData){
        result += Integer.toString((element & 0xff) + 0x100, 16).substring(1);
      }
      return result;

    } catch (Exception e) {
      e.printStackTrace();
      return "";
    }
  }
}
using System;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;

namespace test
{
  class MainClass
  {
    public static void Main(string[] args)
    {
      wyreApi wyreApi = new wyreApi();

      string balance = wyreApi.getAccount();
      Console.WriteLine(balance);

      string transferData = "{" +
        "\"sourceCurrency\": \"USD\"," +
        "\"dest\": \"[email protected]\"," +
        "\"sourceAmount\": \"0.01\"," +
        "\"destCurrency\": \"BTC\"" +
        "}";
      string authResponse = wyreApi.transfer(transferData);
      Console.WriteLine(authResponse);
    }
  }

  public class wyreApi {
    private const string domain = "https://api.sendwyre.com";
    private const string apiKey = "xxxxxx";
    private const string secKey = "xxxxxx";

    public string getAccount() 
    {
      return MakeGetReq("/account");
    }

    public string transfer(string jsonString)
    {
      return MakePostReq("/transfers", jsonString);
    }

    private string MakeGetReq(string apiRoute)
    {
      WebRequest req = AssembleWebRequest(apiRoute);
      req.Method = "GET";
      WebResponse response = req.GetResponse();
      string responseString = ParseWebResponse(response);
      return responseString;
    }

    private string MakePostReq(string apiRoute, string jsonData)
    {
      WebRequest req = AssembleWebRequest(apiRoute, jsonData);
      req.Method = "POST";
      WriteJsonToRequest(req, jsonData);


      WebResponse response = req.GetResponse();
      string responseString = ParseWebResponse(response);
      return responseString;
    }

    private WebRequest AssembleWebRequest(string apiRoute, string jsonData = "")
    {
      string url = domain + apiRoute + (apiRoute.Contains("?")?"&":"?") + "timestamp="+DateTime.Now.Ticks; 
      WebRequest request = WebRequest.Create(url);
      string authSig = CalcAuthSigHash(secKey, url + jsonData);

      request.ContentType = "application/json";
      request.Headers["X-Api-Key"] = apiKey;
      request.Headers["X-Api-Signature"] = authSig;
      request.Headers["X-Api-Version"] = "2";
      return request;
    }

    private void WriteJsonToRequest(WebRequest req, string jsonData)
    {
      var streamWriter = new StreamWriter(req.GetRequestStream ());
      streamWriter.Write(jsonData);
      streamWriter.Close();
    }

    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)));
      hash = hash.Replace("-", "");
      return hash;
    }

    private string ParseWebResponse(WebResponse response)
    {
      StreamReader streamReader = new StreamReader(response.GetResponseStream());
      string result = streamReader.ReadToEnd();
      streamReader.Close();
      return result;
    }
  }
}
<?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"=>"[email protected]",
      "destAmount"=> 55.05,
      "destCurrency"=>"EUR",
      "message"=> "buy sam pizza"
      );
    echo make_authenticated_request("/transfers", "POST", $transfer);
?>

相关链接和联系方式

链接

Wyre主页

Wyre注册页

MassPay开发者中心

参考

区块链技术介绍

公司信息

联系方式

[email protected]
415-374-7356
1550 Bryant St, Ste 750
San Francisco, CA 94107

或者

使用我们主页右下角的在线聊天