记录一个使用第三方USDT支付通道的PHP项目的开发过程及解决方案
- 项目的需求背景
接到一个项目,需要收付USDT,顾客要求用币安链的,即BSC链,需要实现:
充值监控:当用户通过区块链钱包将 USDT 转账到指定地址时,系统能够监控并确认充值到账。
提现功能:当用户发起提现请求时,系统能够根据用户指定的地址,自动完成 USDT 的转账操作。
交易安全性:确保每笔交易都具有合法性,防止双花攻击或伪造交易。
要是都自己做,费钱费力还容易出问题,还是用第三方USDT支付通道吧。想起以前同事用过UBAO.IO,用起来还不错,还是使用UBAO吧。注册地址:https://m.ubao.io/#/login?c=8YmVrlk 。注册后保存商户号和API_SECRET备用。
- 开发过程
代码,用PHP。商业逻辑,倒也没什么说的。主要记录一下支付这一块。
想法是,生成一批钱包地址,保存在本地数据库中,供会员轮流使用,时限24小时。比如,甲会员需要付款,那就调用一个地址A,标记调用时间,24小时内,只要地址A进来的USDT,都认为是甲会员所付(这个时间已经很宽松了,大多数人付款,时间也就几分钟,不会超过半小时)。如果再来乙会员,那就调用地址B,依次类推。24小时后,这些地址释放,供会员轮流调用,这样比较节约地址。毕竟付款的动作,不是每个会员每天都做。
生成地址的代码:
//調用API生成一個錢包地址
$url = "https://api.ubao.id/mch/address/create";
$merchantId = "12345"; //商戶號
$api_key = "123456789"; //商戶密鑰
$timestamp = time();
//結果:1725607713
$nonce = rand(100000,999999);
//結果:212343
$body_data = array('chainType'=>170,'type'=>0,'callUrl'=>'http://www.xxx.com/callback.html');
//把body數組轉為JSON字符串
$str = json_encode($body_data);
//結果:{"chainType":170,"type":0,"callUrl":"http:\/\/www.xxx.com\/callback.html"}
//再用base64編碼,得到最終的body字符串
$body = base64_encode($str);
//結果:eyJjaGFpblR5cGUiOjE2MCwidHlwZSI6MCwiY2FsbFVybCI6Imh0dHA6XC9cL3d3dy54eHguY29tXC94eHguaHRtbCJ9
//簽名
$sign = md5($body . $api_key . $nonce . $timestamp);
//結果:5eab870f6a4fea6caabc6e0be4308bf0
//提交給網關的數據
$data = array('merchantId'=>$merchantId,'timestamp'=>$timestamp,'nonce'=>$nonce,'sign'=>$sign,'body'=>$body);
//用POST方式提交給網關
$res = curlPost($url,$data);
//結果:{"code":200,"message":"SUCCESS","address":"0xD3b0d838cCCEAe7ebF1781D11D1bB741DB7Fe1A8","chainType":170}
//这个address ,就是钱包地址,保存到本地数据库。如果需要更多地址,再调用就是。
//......
function curlPost($url, $post_data = array(),$timeout = 5, $header = array("content-type: application/x-www-form-urlencoded"), $data_type = "") {
$header = empty($header) ? '' : $header;
if($data_type == 'json'){
$post_string = json_encode($post_data);
}elseif($data_type == 'array') {
$post_string = $post_data;
}elseif(is_array($post_data)){
$post_string = http_build_query($post_data, '', '&');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
3.如果有会员付款,UBAO会通知上面留下的回调地址 http://www.xxx.com/callback.html 。然后在这个程序里处理一下。
$api_key = "123456789"; //商戶密鑰
$body = $_POST['body'];
$sign = $_POST['sign'];
$nonce = $_POST['nonce'];
$timestamp = $_POST['timestamp'];
$msg = "";
try {
$sign2 = md5($body . $api_key . $nonce . $timestamp);
if($sign2 != $sign){
$msg = "sign error";
throw new Exception();
}
$json = json_decode(base64_decode($body),true);
$decimals = $json['decimals'];
$amount = number_format($json['amount']/pow(10,$decimals),3,'.','') + 0;
if($json['callbackType'] == 'recharge'){
//充幣的業務邏輯處理
if($json['chainType'] == 170 && $json['coinID'] == 1002){ //币安链的USDT
$address = $json['address'];//收款的地址
//找到本地数据库记录的锁定此地址的会员,将他的付款状态改为付款成功。
。。。。
}
}
if($json['callbackType'] == 'transfer'){
//提幣或轉賬的業務邏輯處理
if($json['result'] == 1){
//轉賬成功
}
else{
//轉賬失敗
$msg = $json['message'];
}
}
if($json['callbackType'] == 'balance'){
//得到地址余額的業務邏輯處理
}
$msg = "SUCCESS";
}
catch (Exception $e) {
//
}
echo $msg;
- 测试与后记
测试起来,挺顺利。顾客也挺满意。收尾款,收工。至于说以后可用地址不足,让他花钱升级就是了。也不麻烦。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步