通过本教程可以快速上手Wyre MassPay API.
什么是MassPay?
客户可以使用MassPay在不同货币间转账。如果您有跨国转账汇款的需求,MassPay是您的首选。
目录:
1. 开设Wyre账户
首先,如果您没有账户,需要创建一个账户。这个过程中需要核对email和手机号。
开始转账前您需要有以下的信息:
- API Key
- SECRET Key
- ACCOUNT ID
这些信息可以在登陆后的Your Account | API Keys里找到。
当生成一个API key后,页面显示如下图。
最后还需要AccountID。可以从key的details链接里找到。
注意
请不要包含"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计算得到的密钥散列消息认证码 |
计算您的密钥散列消息认证码的步骤如下(代码示例在页底):
- 在请求URL后加上毫秒时间戳。例如为了得到账户细节,请求URL为https://api.sendwyre.com/v2/account?timestamp=1426252182534。
- 将请求的URL和HTTP请求内容合并成一个UTF-8字符串。GET请求内容为一个空字符串。
- 用SHA-256和您的API Secret Key计算签名。
以下是Wyre MassPay API节点。点击名称链接进入相应文档。
名称 | API节点 | HTTP方法 | 描述 |
---|---|---|---|
账户详情 | https://api.sendwyre.com/v2/account | GET | 账户详情包括联系方式,所有货币的结余,相关授权和支付方式。 |
实时价格 | https://api.sendwyre.com/v2/rates | GET | 不同交易所的比特币价格。 |
创建转账 | https://api.sendwyre.com/v2/transfers | POST | 创建两种货币间的转账。目的地可以是email地址,比特币钱包地址或者银行账户。可以开启自动确认功能,但并不推荐。 |
转账确认 | https://api.sendwyre.com/v2/transfer/:transferId/confirm | POST | 转账只会在您确认所有细节之后的30秒内执行。 |
转账状态 | https://api.sendwyre.com/v2/transfer/:transferId | GET | 如果您不想用callbackUrl,您可以通过本API获得订单状态。不同订单状态种类在这里。 |
创建第一个转账请求
一个转账请求是一个包含最多7个字段的JSON POST请求。
sourceAmount
- 只需要选择sourceAmount
或者destAmount
中一个。sourceAmount
是从主账户中扣除的用来转账的金额。这种情况下您可以指定从账户中扣除的金额,入账金额将由交易费用和汇率确定。sourceCurrency
- 转出货币代码ISO 3166-1 alpha-3dest
- 转账地址。可以是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 .= '×tamp=' . $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);
?>
相关链接和联系方式
链接
参考
联系方式
[email protected]
415-374-7356
1550 Bryant St, Ste 750
San Francisco, CA 94107
或者
使用我们主页右下角的在线聊天