该接口提供实时汇率换算、外汇报价、货币汇率以及币种之间的汇率转换,广泛用于国际结算、银行汇率查询应用、开展跨国贸易、投资等参考场景。提供高效稳定的解决方案。
汇率行情仅供参考,旨在提供市场动态和信息,不构成任何形式的投资或交易建议
接口包含四个子接口:所有货币种类列表、实时汇率查询换算、单个货币列表、银行汇率实时查询。
接口能力概述
四个子接口的实际用法
1. 货币种类列表:/list
这个接口用来获取系统支持的所有货币代码。我们的用法是在系统初始化时调用一次,把返回的币种列表缓存到 Redis 里,前端下拉框的币种选项直接从缓存读。
import urllib3 import json host = 'https://market.aliyun.com/detail/cmapi00065831' path = '/list' url = host + path appcode = '你的AppCode' http = urllib3.PoolManager() headers = {'Authorization': 'APPCODE ' + appcode} response = http.request('GET', url, headers=headers) content = json.loads(response.data.decode('utf-8')) if content.get('code') == 1: currency_list = content['data']['list'] # currency_list 格式: [{"currency": "CNY", "name": "人民币"}, ...] for item in currency_list: print(f"{item['currency']} - {item['name']}")返回的data.list是一个数组,每个元素包含currency(货币代码)和name(中文名称)。目前支持的币种有一百多种,基本覆盖了我们业务需要的所有货币。
2. 实时汇率查询换算:/index
这是最常用的接口。传入源币种、目标币种和金额,直接返回换算结果。
import urllib3 import json host = 'https://market.aliyun.com/detail/cmapi00065831' path = '/index' appcode = '你的AppCode' querys = 'from=CNY&to=USD&money=100' url = host + path + '?' + querys http = urllib3.PoolManager() headers = {'Authorization': 'APPCODE ' + appcode} response = http.request('GET', url, headers=headers) content = json.loads(response.data.decode('utf-8')) if content.get('code') == 1: data = content['data'] print(f"汇率: 1 {data['from']} = {data['exchange']} {data['to']}") print(f"换算结果: {data['money']} {data['to']}") print(f"更新时间: {data['updatetime']}")参数说明:
from:源货币代码to:目标货币代码money:换算金额,默认 1
返回的exchange是当前汇率,money是按传入金额换算后的结果。注意看updatetime字段,数据大约每分钟更新一次,但由于上游数据源的延迟,部分币种的更新时间可能会有几十分钟的滞后。如果实时性要求高的场景,建议在调用后检查一下updatetime距当前时间是否在可接受范围内。
3. 单个货币汇率列表:/single
这个接口的好处是一次请求可以拿到某个币种对所有其他货币的汇率。我们用它来做页面上的汇率速览卡片,比如"人民币对全球主要货币汇率一览",避免前端循环请求多个币种对。
import urllib3 import json host = 'https://market.aliyun.com/detail/cmapi00065831' path = '/single' appcode = '你的AppCode' querys = 'from=CNY' url = host + path + '?' + querys http = urllib3.PoolManager() headers = {'Authorization': 'APPCODE ' + appcode} response = http.request('GET', url, headers=headers) content = json.loads(response.data.decode('utf-8')) if content.get('code') == 1: data = content['data'] print(f"基准货币: {data['currency']} {data['name']}") for currency_code, rate_info in data['list'].items(): print(f" {currency_code} ({rate_info['name']}): {rate_info['rate']}")4. 银行汇率实时查询:/bank
这个子接口查询的是银行的实时外汇牌价,包含汇买、汇卖、钞买、钞卖四个价格。我们用它来做结算系统里的换汇成本估算。
import urllib3 import json host = 'https://market.aliyun.com/detail/cmapi00065831' path = '/bank' appcode = '你的AppCode' querys = 'bank_code=ICBC' url = host + path + '?' + querys http = urllib3.PoolManager() headers = {'Authorization': 'APPCODE ' + appcode} response = http.request('GET', url, headers=headers) content = json.loads(response.data.decode('utf-8')) if content.get('code') == 1: data = content['data'] print(f"银行: {data['name']}") print(f"发布时间: {data['time']}") for item in data['code_list']: print(f" {item['code']} {item['name']}") print(f" 汇买: {item['hui_in']} | 汇卖: {item['hui_out']}") print(f" 钞买: {item['chao_in']} | 钞卖: {item['chao_out']}")参数bank_code填银行简码,比如 ICBC(工商银行)、BOC(中国银行)、CCB(建设银行)等。返回里的四个价格字段含义:
hui_in:银行买入价(汇买)——银行从你手里买外汇时的价格hui_out:银行卖出价(汇卖)——银行卖外汇给你时的价格chao_in:钞币买入价(现钞买入)chao_out:钞币卖出价(现钞卖出)
跨境结算时实际换汇成本用的是hui_out(银行卖给你外汇的价格),这个价差是我们财务核算时的一个关键参数。
接入中踩过的几个坑
坑 1:接口限流
这套接口的 QPS 限制是 5。刚开始我们没有做限流控制,批量查询时直接并发请求,连续几次之后返回了 403。后来加了一个简单的间隔控制,每次请求之间 sleep 200ms,就没再触发过限流。
import time def batch_query(pairs, interval=0.2): """批量查询汇率,控制请求间隔""" results = [] for from_currency, to_currency in pairs: # 每次请求之间等待 time.sleep(interval) result = query_rate(from_currency, to_currency) results.append(result) return results如果业务场景需要更高的并发,建议提前跟平台申请 QPS 提升,不要硬扛限流。
坑 2:AppCode 泄露风险
最早我们把 AppCode 写在了配置文件里,还上传到了代码仓库。后来意识到这个问题,把密钥管理改成了环境变量注入,CI/CD 流水线里用 Secret 管理。这个是最基础但最容易被忽略的安全问题。
坑 3:汇率精度处理
汇率数据返回的都是字符串类型(比如"7.239500"),直接转 float 进行计算会有精度问题。金额相关的计算一定要用Decimal:
from decimal import Decimal, ROUND_HALF_UP rate = Decimal("7.2395") amount = Decimal("100.00") result = (amount * rate).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP) # 结果: Decimal('723.95')这个问题在结算系统里尤其重要,几分钱的偏差日积月累下来就是不小的数字。
坑 4:数据延迟的判断
不是所有请求失败才叫异常。有时候接口返回了 200,但updatetime距离当前时间已经过了好几个小时,这种"静默延迟"比 outright 报错更难发现。我们在代码里加了一个检查逻辑:
from datetime import datetime, timedelta def is_rate_fresh(updatetime_str, max_delay_minutes=10): """检查汇率数据是否在可接受的延迟范围内""" update_time = datetime.strptime(updatetime_str, "%Y-%m-%d %H:%M:%S") return datetime.now() - update_time < timedelta(minutes=max_delay_minutes)如果检测到数据过期,就降级使用上一次缓存的结果,同时触发告警。
写在最后
汇率数据在跨境业务里是一个"平时感觉不到,出问题时很痛"的隐性依赖。免费方案的限制往往在业务跑起来之后才显现出来,那时候再换数据源,历史数据补录、对账差异排查都是额外的工作量。
这套接口接入我们的系统大概半年了,整体比较稳定,数据延迟基本控制在分钟级,银行的牌价数据对结算成本估算帮助很大。唯一需要注意的是 QPS 限制和精度处理,把这两件事做好,日常使用基本没有其他问题。
接口文档
API 官方文档:https://market.aliyun.com/detail/cmapi00065831
(注意:本文档可能更新,请以官网为准。)