接口基础信息
加密方式
支付 API
代付 API
余额 API
代码示例
基础信息
- 所有 API 请求都应以 JSON 格式在请求体中发送。
- 所有响应均采用 JSON 格式。
- Base URL:
https://api.webviopay.com -
参数解析:
api_secret: 接口密钥.client_id: 商户唯一标识.hash_key: 加密 hash key.YOUR_CALLBACK_URL: 回调发送的 URL.
- 请联系客服将您的IP地址添加到白名单中。
-
重要提示:您的 IP 地址必须列入白名单才能发起支付和代付。
HMAC SHA256
-
我们使用
HMAC签名算法SHA256 - 先把参数按 ASCII 排序拼好,再拼接 &secret=api_secret,然后用 HashKey 采用 HMAC SHA256算法 进行加密,最终得到的加密串作为sign 。
-
将所有需要签名的字段按 ASCII 码升序排序,并按
a=b&c=d的格式连接成一个字符串,-
ASCII码排序前如下:
-
client_id=xxx&name=test&amount=100&mobile=121212&orderid=121212&email=test@gmail.com
-
-
ASCII码排序后如下:
-
amount=100&client_id=xxx&email=test@gmail.com&mobile=121212&name=test&orderid=121212
-
-
ASCII码排序前如下:
-
然后使用
&secret=api_secret(api_secret 是商户的密钥)拼接商户的密钥,生成待签名的字符串如下。-
amount=100&client_id=xxx&email=test@gmail.com&mobile=121212&name=test&orderid=121212&secret=api_secret
-
-
除了
sign以外不为空的参数都需要参与签名 - 对生成的字符串执行 HMAC 签名,以获得最终签名字符串。
-
最终加密结果:
-
7697c728da9a8aa4ca5ee72c507ce35cb01f8c598e3c934dfd644c00a4513b04
-
1. 代收 API
1.1 Initiate Payin
接口请求地址:
POST https://api.webviopay.com/api/payin/create/order
请求参数:
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
name |
String | Yes | 姓名. |
amount |
String | Yes | 金额 (e.g.,"100") |
mobile |
String | Yes | 手机号(10位数字) |
orderid |
String | Yes | 单号唯一 (最大 64 字符) |
email |
String | Yes | 邮箱 |
client_id |
String | Yes | 商户唯一标识 |
sign |
String | Yes | 签名字符串 |
请求:
{
"client_id": "TK1212121212",
"name": "aprul",
"amount": "100",
"mobile": "9564584545",
"orderid": "xxxxxxxxxxxxxxxxx",
"email": "pp456@gmail.com",
"sign": "xxxxxxxxxxxxx"
}
返回成功:
{
"statusCode": 200,
"message": "success",
"orderid": "xxxxxxxxxxxxxxxxx",
"qr": "upi://pay?pa=xxxtltd@finobank",
"pay_link":"https://pay.apsisi.com?or=ddd",
"referenceid":"123456890000"
}
返回错误:
{
"statusCode" = 400,
"message" = "some error message"
}
返回参数解析:
| 参数 | 类型 | 描述 |
|---|---|---|
statusCode |
Intval | 返回状态码 : 200 Success , 400 Failed |
message |
String | 信息 |
pay_link |
String | 付款链接 |
qr |
String | 深度链接 |
orderid |
String | 商户单号 |
referenceid |
String | 平台单号 |
1.2 支付回调
WebvioPay 会将异步支付状态更新发送到您提供的 callback_url。
Endpoint:
POST YOUR_CALLBACK_URL
| 参数 | 类型 | 描述 |
|---|---|---|
statusCode |
String | 支付状态 : 200 or 400 |
message |
String | 支付状态描述: SUCCESS or FAILED |
orderid |
String | 商户单号 |
referenceid |
String | 平台单号 |
Utr |
String | UTR |
PayerAmount |
Intval | 支付金额 |
client_id |
String | 商户唯一标识 |
sign |
String | 签名 |
回调成功:
{
"client_id": "TX12121212",
"sign": "xxxxxxxxxxxxxx",
"statusCode": 200,
"message": "Success",
"orderid": "xxxxxxxxxxxxxxxxx",
"referenceid": "1234567890",
"Utr": "5454212121211",
"PayerAmount": 100,
}
回调失败:
{
"client_id": "TX12121212",
"sign": "xxxxxxxxxxxxxx",
"statusCode": 203,
"message": "Failed",
"orderid": "xxxxxxxxxxxxxxxxx",
"referenceid": "1234567890",
"Utr": "",
"PayerAmount": 0,
}
回调支付中:
{
"client_id": "TX12121212",
"sign": "xxxxxxxxxxxxxx",
"statusCode": 202,
"message": "Pending",
"orderid": "xxxxxxxxxxxxxxxxx",
"referenceid": "1234567890",
"Utr": "",
"PayerAmount": 0,
}
注意:请确保您的回调 URL 可公开访问,并已配置为处理来自 WebvioPay 的 POST 请求。
回调中的 orderid 将与您在初始化过程中发送的 orderid 相对应。
1.3 支付查单
获取 支付订单 交易的当前状态。
接口地址:
POST https://api.webviopay.com/api/payin/check/order
请求参数:
| 参数 | 类型 | 描述 |
|---|---|---|
client_id |
String | 商户唯一标识 |
sign |
String | 签名字符串 |
orderid |
String | 商户单号 |
请求示例:
{
"client_id": "TX12121212",
"sign": "xxxxxxxxxxxxxx",
"orderid": "xxxxxxxxxxxxxxxxxxxx"
}
错误返回:
{
"statusCode" = 400,
"message" = "some error message"
}
订单成功返回:
{
"statusCode": 200,
"message": "Success",
"orderid": "xxxxxxxxxxxxxxxxxxxx",
"Utr": "123122121212",
"referenceid": "1234567890",
"PayerAmount": 100,
}
订单失败返回:
{
"statusCode": 203,
"message": "Failed",
"orderid": "xxxxxxxxxxxxxxxxxxxx",
"Utr": "",
"referenceid": "1234567890",
"PayerAmount": 0,
}
订单支付中:
{
"statusCode": 202,
"message": "Pending",
"orderid": "xxxxxxxxxxxxxxxxxxxx",
"Utr": "",
"referenceid": "1234567890",
"PayerAmount": 0
}
2. 代付 API
2.1 接口请求地址
POST https://api.webviopay.com/api/payout/create/order
请求参数:
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
amount |
String | Yes | 金额 (e.g.,"100") |
orderid |
String | Yes | 商户单号(最大64 字符). |
email |
String | Yes | 受益人邮箱 |
accountHolderName |
String | Yes | 受益人姓名 |
mobileNumber |
String | Yes | 受益人手机号 (10位数字) |
accountNumber |
String | Yes | 受益人卡号 |
ifscCode |
String | Yes | IFSC |
bankName |
String | Yes | 银行名称 |
client_id |
String | Yes | 商户唯一标识 |
sign |
String | Yes | 签名字符串 |
请求demo:
{
"client_id": "TX12121212",
"sign": "xxxxxxxxxxxxxx",
"accountHolderName": "Apurls xpus",
"mobileNumber": "9665555555",
"amount": "100",
"orderid": "1111111111111111111",
"accountNumber": "78787878787",
"ifscCode": "IDFB000XXXX",
"bankName": "IDFB",
"email":"APRIS544@gmail.com"
}
失败返回:
{
"statusCode" = 400,
"message" = "Submission failed, some error messages"
}
提交成功:
{
"statusCode" = 202,
"message" = "Pending",
"orderid": "1111111111111111111",
"referenceid":"1234567890",
"Utr":"",
"amount": "100",
}
2.2 代付回调
WebvioPay会将异步代付状态更新发送到您配置的回调URL。
Endpoint:
POST YOUR_CALLBACK_URL_FOR_PAYOUTS
| 参数 | 类型 | 描述 |
|---|---|---|
statusCode |
String | 代付状态: 200 or 203 or 202 or 201 |
message |
String | 状态描述: Success,Failed ,Pending,Reversal |
orderid |
String | 商户单号. |
referenceid |
String | 平台单号 |
Utr |
String | UTR |
amount |
String | 金额 |
client_id |
String | 商户唯一标识 |
sign |
String | 签名 |
订单成功回调:
{
"client_id": "TX12121212",
"sign": "xxxxxxxxxxxxxx",
"statusCode": 200,
"message": "Success",
"orderid": "1111111111111111111",
"referenceid":"1234567890",
"Utr": "521809061729",
"amount":"100",
}
订单处理中回调:
{
"client_id": "TX12121212",
"sign": "xxxxxxxxxxxxxx",
"statusCode": 202,
"message": "Pending",
"orderid": "1111111111111111111",
"referenceid":"1234567890",
"Utr": "",
"amount":"100",
}
订单失败回调:
{
"client_id": "TX12121212",
"sign": "xxxxxxxxxxxxxx",
"statusCode": 203,
"message": "Failed",
"orderid": "1111111111111111111",
"referenceid":"1234567890",
"Utr": "",
"amount":"100",
}
订单冲正回调:
{
"client_id": "TX12121212",
"sign": "xxxxxxxxxxxxxx",
"statusCode": 201,
"message": "Reversal",
"orderid": "1111111111111111111",
"referenceid":"1234567890",
"Utr": "123456789",
"amount":"100",
}
注意:请确保您的回调 URL 可公开访问,并已配置为处理来自 WebvioPay 的 POST 请求。
回调中的订单ID 将与您在发起订单时发送的订单ID 相对应。
订单冲正状态表示订单最初成功,但随后失败。
2.3 代付单查询
获取付款交易的订单当前状态。
接口地址:
POS https://api.webviopay.com/api/payout/check/order
请求参数:
| 参数 | 类型 | 描述 |
|---|---|---|
orderid |
String | 商户单号 |
client_id |
String | 商户唯一标识 |
sign |
String | 签名 |
请求示例:
{
"client_id": "TX12121212",
"sign": "xxxxxxxxxxxxxx",
"orderid": "12312312312312",
}
错误返回:
{
"statusCode": 400,
"message": "Other error"
}
订单成功返回:
{
"statusCode": 200,
"message": "Success",
"orderid": "12312312312312",
"referenceid":"1234567890",
"Utr": "123456789",
"amount":"100",
}
订单失败返回:
{
"statusCode": 203,
"message": "Failed",
"orderid": "12312312312312",
"referenceid":"1234567890",
"Utr": "",
"amount":"100",
}
订单处理中返回:
{
"statusCode": 202,
"message": "Pending",
"orderid": "12312312312312",
"referenceid":"1234567890",
"Utr": "",
"amount":"100",
}
订单冲正返回:
{
"statusCode": 201,
"message": "Reversal",
"orderid": "12312312312312",
"referenceid":"1234567890",
"Utr": "121212121212",
"amount":"100",
}
3. 余额 API
3.1 查询商户余额
POST https://api.webviopay.com/api/merchant/wallet
请求参数:
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
client_id |
String | Yes | 商户唯一标识 |
sign |
String | Yes | 签名 |
请求示例:
{
"client_id": "TX12121212",
"sign": "xxxxxxxxxxxxxx"
}
成功返回:
{
"statusCode": 200,
"message": "Wallet balance successfully.",
"data": {
"balance": 1722.69
},
}
失败返回:
{
"statusCode": 400,
"message": "other error."
}
4. 加密代码示例
4.1 PHP code
/**
* HMAC签名
*/
public function hmacSign($data, $hash_key) {
return hash_hmac('sha256', $data, $hash_key);
}
4.2 JAVA code
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HexFormat;
public class HmacSigner {
/**
* 计算 HMAC 签名(默认使用 SHA256)
*
* @param data 要签名的数据
* @param hashKey 密钥(字符串形式)
* @return HMAC 签名的十六进制字符串
*/
public static String hmacSign(String data, String hashKey) {
return hmacSign(data, hashKey, "SHA256");
}
/**
* 计算 HMAC 签名(指定算法)
*
* @param data 要签名的数据
* @param hashKey 密钥(字符串形式)
* @param algorithm 算法:SHA256、SHA1、MD5 等
* @return HMAC 签名的十六进制字符串
*/
public static String hmacSignChoose(String data, String hashKey, String algorithm) {
try {
// 将算法名称转换为 Java 标准格式
String javaAlg = algorithm.toUpperCase();
if (!javaAlg.startsWith("HMAC")) {
javaAlg = "Hmac" + javaAlg;
}
// 创建密钥规范
SecretKeySpec secretKeySpec = new SecretKeySpec(
hashKey.getBytes(StandardCharsets.UTF_8),
javaAlg
);
// 获取 MAC 实例并初始化
Mac mac = Mac.getInstance(javaAlg);
mac.init(secretKeySpec);
// 计算 HMAC
byte[] hashBytes = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
// 转换为十六进制字符串
return HexFormat.of().formatHex(hashBytes);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("不支持的算法: " + algorithm, e);
} catch (InvalidKeyException e) {
throw new RuntimeException("无效的密钥", e);
}
}
public static void main(String[] args) {
String data = "Hello, World!";
String key = "my-secret-key-123";
// 示例 1: 默认使用 SHA256
String signature1 = HmacSigner.hmacSign(data, key);
System.out.println("SHA256 HMAC: " + signature1);
// 示例 2: 指定 SHA256 算法
String signature2 = HmacSigner.hmacSignChoose(data, key, "SHA256");
System.out.println("SHA1 HMAC: " + signature2);
}
}
4.1 Python code
import hmac
import hashlib
from typing import Iterator
class StreamingHmacSigner:
"""流式 HMAC 签名,适用于大文件"""
def __init__(self, key: bytes, algorithm: str = 'sha256'):
self.key = key
self.algorithm = algorithm
# 创建 HMAC 对象
if algorithm == 'sha256':
self.digestmod = hashlib.sha256
elif algorithm == 'sha1':
self.digestmod = hashlib.sha1
elif algorithm == 'md5':
self.digestmod = hashlib.md5
else:
raise ValueError(f"不支持的算法: {algorithm}")
self.hmac_obj = hmac.new(self.key, digestmod=self.digestmod)
def update(self, data: bytes):
"""更新数据块"""
self.hmac_obj.update(data)
def digest(self, format: str = 'hex') -> Union[str, bytes]:
"""获取最终签名"""
signature = self.hmac_obj.digest()
if format == 'hex':
return signature.hex()
elif format == 'base64':
import base64
return base64.b64encode(signature).decode('utf-8')
else:
return signature
@classmethod
def sign_file(
cls,
filepath: str,
key: bytes,
algorithm: str = 'sha256',
chunk_size: int = 8192
) -> str:
"""计算文件的 HMAC 签名"""
signer = cls(key, algorithm)
with open(filepath, 'rb') as f:
while chunk := f.read(chunk_size):
signer.update(chunk)
return signer.digest('hex')