<?php
|
|
namespace app\home\controller;
|
|
/**
|
* PHP版万里汇API签名生成工具
|
* 对应JavaScript逻辑:RSA-SHA256签名 + Base64编码
|
*/
|
|
use app\BaseController;
|
use think\facade\Request;
|
|
class Wftest extends BaseController
|
{
|
private $config = [
|
'domain' => 'https://open-sitprod-sg.alipay.com', // 万里汇API测试域名,测试时需要把ip发给万里汇技术加白才能开发测试
|
'is_sandbox' => 0, // 是否沙箱环境,true为沙箱环境,false为正式环境
|
'ClientID' => '3J5Y8Y382Y3K3105035', //商户id
|
'CustomerId' => '2120120007146804', //开发者中心customer id
|
'MID' => '2120120235023340', //门户帐号MID
|
'CertificationType' => 'RSA2', //商户密钥
|
'publicKey' => 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiBMwCt/FA7NlSX0x0oYaxgAgbJy61K5MuvsxBNm7QvOzKNcC17kxoVh17gl1jKmZt+OVaWyzzxxg1P1KBtJvdIWRvt87XD31uYRe75F6NTWi0Okc6mJ0TgHYaZX25eufWiIDzR+rsyolaL3F+INfoXvIbygP8YG/wxdYqssRiUq546j2vlIIgmY9LpByEJwQcLEzaJqcw1lpfoogOLBa/opRVn5FavVaI58gHMqWCcc9LIohrqywyZehv6bV/1h0cZ1MN/7nnCF1S16iAZqL1Tqgo+RMKDzJ2zvRyMSl+N8ZXcmWVDalreaV4+mi8rZBBooJ4mEmXEFKHIB09+ALwQIDAQAB', //公钥
|
'privateKey' => 'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCIEzAK38UDs2VJfTHShhrGACBsnLrUrky6+zEE2btC87Mo1wLXuTGhWHXuCXWMqZm345VpbLPPHGDU/UoG0m90hZG+3ztcPfW5hF7vkXo1NaLQ6RzqYnROAdhplfbl659aIgPNH6uzKiVovcX4g1+he8hvKA/xgb/DF1iqyxGJSrnjqPa+UgiCZj0ukHIQnBBwsTNompzDWWl+iiA4sFr+ilFWfkVq9VojnyAcypYJxz0siiGurLDJl6G/ptX/WHRxnUw3/uecIXVLXqIBmovVOqCj5EwoPMnbO9HIxKX43xldyZZUNqWt5pXj6aLytkEGigniYSZcQUocgHT34AvBAgMBAAECggEAJKe2i1dYBPUwVamJ4EILuEaUdW2KznvdY4kC3WGhlhl7q4av11ily+a+bc7SgX+2TtjZiLqlfScR1o4cgNXy/Bp29km//csbBExqHnK7ztWR9GC3T1QSLGlG2Lpy9eCQ3oDHMVxUrkCuLxbf21/YRPHJPlg2Y0ImW/FQC0IEiUzZUr5Owg7zNzDYcyjt1A0I9w2GCxgaZDxxoNE/AwD5cp0dc3+LT/QKdIVY/hxQZ3BlE541pk5LsLQN5639DyivQx4LouTTu5LaYOdd9EW/f/9YxUOnYwBA2A1Yd/OVJhyuAI8fV31hp+vFNlcRKnGQg5I69L24E+LKUmOuC/d4AQKBgQC8rNzleFiSyxgT/oKUk7RNjvBnbmP2ADiWeAsAxWo+nmDcrSj1QxJ/SdQ5r30An0onaZ3R2kD1Oz7t4s/H+yFNhA6/ZEWe8zAxYqGBIgCoNpDPgY382eF5CJpea9zXSKxv5XuIlFbtpNh1HBBEp2uUKjSx9448fcEzn/SogMeCIQKBgQC4oWJzHtrm/toojLIAczTGkFZuSs7GIyuk3XI4L3BF6ZCdV57SPJpYGhe7twk3+bBEE8pyvZjcFOtMaqk4kxyUh3N6+ixw/uy2cPbqs/yOlv6bgC5kyXmf/lzh7a6vxtJnJ1Cxvxv/TZ/CYLbVjp+jEhAqi0+NTPwvHvxgumqVoQKBgBDyujkGsXYmNjh9kT9FcVnSMDgqS2JqrKqfh+V+1kdftLW9/ELjzoKOoDi6UdE/fcrCiwGxyEn/E20NBbsiDODIrwZ0PGjF0ZtuD7Ho2wRBOorZSWbgL4fOxQccS08vYQYAKDOhl5lrSGJkrfVs0JYToH4oDafTaAp6IOEOCF3hAoGBAI5AWZgVB9e+N9vSOzs5iEoM32ru3E2wv2mw7NX5Rum2wSNZZRbadpi20d5hcgrcqEBrdynchq/atkgUTfk272hIzGLN6fvNjhgrBTNkJYy/LcAljJk+2iS5WFsCQ/tOlsG/et7YPfwAlLyww23bC4ga3LXKzCo0TIEJwK3OM1zBAoGBAICf031sETlA3ICd1oynfFuLDIp7erRxZgWmh2fgASY1a98LR7nvm4F7XgUHeinILIiHLrdaQtS439DydEC8wf2Q+GlcQqyv048He+8vgjNoz7CP9kqYyIex567K/MJTrRkh3KHMSyX1oaSXrgvW4/6SYvCX2hlxXeOnLJie6LVe', //商户私钥privateKey
|
];
|
// ISO 4217标准货币最小单位(小数点位数)
|
private static $currencyUnits = [
|
'AUD' => 2,
|
'BDT' => 2,
|
'BRL' => 2,
|
'CAD' => 2,
|
'CLP' => 0,
|
'CNY' => 2,
|
'EUR' => 2,
|
'GBP' => 2,
|
'HKD' => 2,
|
'IDR' => 2,
|
'JPY' => 0,
|
'KRW' => 0,
|
'MXN' => 2,
|
'MYR' => 2,
|
'NZD' => 2,
|
'PEN' => 2,
|
'PHP' => 2,
|
'PKR' => 2,
|
'PLN' => 2,
|
'SGD' => 2,
|
'THB' => 2,
|
'TWD' => 2,
|
'USD' => 2,
|
'VND' => 0
|
];
|
//获取货币最小单位对应的值
|
private function getCurrenyMoneytoMinorUnit(float $amount, string $currency): int
|
{
|
$currency = strtoupper($currency);
|
if (!isset(self::$currencyUnits[$currency])) {
|
return "Unsupported currency: {$currency}";
|
}
|
$decimals = self::$currencyUnits[$currency];
|
return (int)round($amount * pow(10, $decimals));
|
}
|
//将最小单位值转换回标准金额
|
private function getCurrenyMoneyfromMinorUnit(int $minorValue, string $currency): float
|
{
|
$currency = strtoupper($currency);
|
if (!isset(self::$currencyUnits[$currency])) {
|
return "Unsupported currency: {$currency}";
|
}
|
$decimals = self::$currencyUnits[$currency];
|
return $minorValue / pow(10, $decimals);
|
}
|
public function index()
|
{
|
// 从表单获取的参数(模拟$_POST)
|
//获取请求时间(<Request-Time>) 为 2022-04-28T12:31:30+08:00,时间遵循ISO 8601标准
|
$requestTime = date('Y-m-d\TH:i:sP');
|
$clientId = $this->config['is_sandbox'] == 1 ? 'SANDBOX_' . $this->config['ClientID'] : $this->config['ClientID'];
|
$post_data = ["paymentId" => "202205311234234"];
|
// 包裹私钥
|
$privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($this->config['privateKey'], 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----";
|
$publicKey = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($this->config['publicKey'], 64, "\n", true) . "\n-----END PUBLIC KEY-----";
|
$httpMethod = 'POST'; // 请求方法(GET/POST等)
|
$api_url = '/amsin/api/v1/business/inquiryPayOrder'; // 请求API路径
|
$bodyData = json_encode($post_data); // 请求体JSON字符串
|
$params = [
|
'clientId' => $clientId,
|
//'customerId' => $this->config['CustomerId'],
|
'requestTime' => $requestTime,
|
'httpMethod' => $httpMethod,
|
'api' => $api_url,
|
'bodyData' => $bodyData,
|
'privkey' => $privateKey,
|
];
|
$signatureBody = $this->getSignatureBody($post_data, $httpMethod, $api_url, $requestTime);
|
// 生成签名
|
$signature = $this->generateSignature($signatureBody, $privateKey);
|
|
// 验证签名示例(需要公钥)
|
$isValid = $this->verifySignature(
|
$signatureBody,
|
$signature,
|
$publicKey
|
);
|
$params['signature'] = $signature;
|
$params['isValid'] = $isValid;
|
$res = [
|
'isValid' => $isValid,
|
|
//'signature' => $signature,
|
];
|
return dhkSuccess($res);
|
//echo $signature;
|
}
|
public function indexjj()
|
{
|
// 从表单获取的参数(模拟$_POST)
|
//获取请求时间(<Request-Time>) 为 2022-04-28T12:31:30+08:00,时间遵循ISO 8601标准
|
$requestTime = date('Y-m-d\TH:i:sP');
|
$clientId = $this->config['is_sandbox'] == 1 ? 'SANDBOX_' . $this->config['ClientID'] : $this->config['ClientID'];
|
$post_data = [
|
"inquiryRateConditionList" => [
|
[
|
"sellCurrency" => "USD",
|
"buyCurrency" => "CNY"
|
],
|
[
|
"sellCurrency" => "USD",
|
"buyCurrency" => "GBP"
|
]
|
]
|
];
|
// 包裹私钥
|
$privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($this->config['privateKey'], 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----";
|
$publicKey = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($this->config['publicKey'], 64, "\n", true) . "\n-----END PUBLIC KEY-----";
|
$httpMethod = 'POST'; // 请求方法(GET/POST等)
|
$api_url = '/amsin/api/v1/business/fund/inquiryRate'; // 请求API路径
|
$bodyData = json_encode($post_data); // 请求体JSON字符串
|
$params = [
|
'clientId' => $clientId,
|
//'customerId' => $this->config['CustomerId'],
|
'requestTime' => $requestTime,
|
'httpMethod' => $httpMethod,
|
'api' => $api_url,
|
'bodyData' => $bodyData,
|
'privkey' => $privateKey,
|
];
|
$signatureBody = $this->getSignatureBody($post_data, $httpMethod, $api_url, $requestTime);
|
// 生成签名
|
$signature = $this->generateSignature($signatureBody, $privateKey);
|
|
// 验证签名示例(需要公钥)
|
$isValid = $this->verifySignature(
|
$signatureBody,
|
$signature,
|
$publicKey
|
);
|
$params['signature'] = $signature;
|
$params['isValid'] = $isValid;
|
$res = [
|
'isValid' => $isValid,
|
'signature' => $signature,
|
];
|
return dhkSuccess($params);
|
//echo $signature;
|
}
|
//发起第一个请求---获取
|
//沙箱测试通过,线上测试未通过
|
public function getFirst()
|
{
|
$post_data = [
|
"inquiryRateConditionList" => [
|
[
|
"sellCurrency" => "USD",
|
"buyCurrency" => "CNY"
|
],
|
[
|
"sellCurrency" => "USD",
|
"buyCurrency" => "GBP"
|
]
|
]
|
];
|
$requestTime = date('Y-m-d\TH:i:sP');
|
$httpMethod = 'POST'; // 请求方法(GET/POST等)
|
|
$api_url = '/amsin/api/v1/business/fund/inquiryRate'; //支付完成后,集成商可以使用此接口来查询支付结果。
|
$signatureBody = $this->getSignatureBody($post_data, $httpMethod, $api_url, $requestTime);
|
// 包裹私钥
|
$privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($this->config['privateKey'], 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----";
|
|
// 生成签名
|
$signature = $this->generateSignature($signatureBody, $privateKey);
|
$post_url = $this->config['domain'] . $api_url;
|
$header = [];
|
$clientId = $this->config['is_sandbox'] == 1 ? 'SANDBOX_' . $this->config['ClientID'] : $this->config['ClientID'];
|
$header['client-id'] = $clientId;
|
$header['request-time'] = $requestTime;
|
$header['Content-Type'] = 'application/json';
|
$header['signature'] = 'algorithm=RSA256,keyVersion=1,signature=' . $signature;
|
$dhkhttp = new \app\common\toole\Dhkhttp();
|
echo_dhklog($api_url, '请求地址:', 'worldfirst_pay');
|
$res = $dhkhttp->dhkpost($post_url, $post_data, $header);
|
return dhkSuccess($res);
|
}
|
//用户开通--构建重定向URL--暂未开放
|
public function goLoginAuth()
|
{
|
//1. 构建待签名字符串,按照以下格式拼接:顺序不能变,每个参数之间用&符号连接。
|
//格式:clientId=clientId&redirectUrl=redirectUrl&referenceCustomerId=referenceCustomerId&storeUrl=storeUrl&storeName=storeName¤cy=currency&requestId=requestId
|
$clientId = $this->config['is_sandbox'] == 1 ? 'SANDBOX_' . $this->config['ClientID'] : $this->config['ClientID'];
|
$redirectUrl = "http://zhc.develop.dahuiku.com/home/testpay/getAuth"; // 授权成功后的回调地址
|
$referenceCustomerId = "dhk-2"; //由本站卖家用户的唯一ID
|
$storeUrl = "http://zhc.develop.dahuiku.com/seller/index/index.html?sid=2"; //本站卖家店铺地址
|
$storeName = "一火TEST"; //本站卖家店铺名称
|
$currency = "CNY"; //代表RA账户的币种
|
$requestId = "dhk" . Date('YmdHis') . uniqid(); //集成商指定给每个跳转URL的唯一请求ID
|
$post_data = [
|
"clientId" => $clientId,
|
"redirectUrl" => $redirectUrl,
|
"referenceCustomerId" => $referenceCustomerId,
|
"storeUrl" => $storeUrl,
|
"storeName" => $storeName,
|
"currency" => $currency,
|
"requestId" => $requestId,
|
];
|
//格式化成get请求字符串
|
$signatureBody = http_build_query($post_data);
|
|
//$signatureBody = "clientId={$clientId}&redirectUrl={$redirectUrl}&referenceCustomerId={$referenceCustomerId}&storeUrl={$storeUrl}&storeName={$storeName}¤cy={$currency}&requestId={$requestId}";
|
$raw = "clientId={$clientId}&redirectUrl=" . urlencode($redirectUrl) . "&referenceCustomerId={$referenceCustomerId}&storeUrl=" . urlencode($storeUrl) . "&storeName={$storeName}¤cy={$currency}&requestId={$requestId}";
|
//2、字符串编码使用 base64 编码和使用 urlencode编码
|
//$signatureBody = base64_encode($getRaw); //对字符串进行base64编码
|
//$signatureBody = urlencode($signatureBody); //对字符串进行URL编码
|
//3、使用商户私钥对编码后的字符串进行签名
|
$privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($this->config['privateKey'], 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----";
|
$signature = $this->generateSignature($signatureBody, $privateKey); //对字符串进行签名
|
//4、给URL加签和把其中的url进行编码
|
$GET_DATA = "clientId={$clientId}&redirectUrl=" . urlencode($redirectUrl) . "&referenceCustomerId={$referenceCustomerId}&storeUrl=" . urlencode($storeUrl) . "&storeName={$storeName}¤cy={$currency}&requestId={$requestId}";
|
|
$ss_url = "https://portal.worldfirst.com/enterprise/auth?" . $signatureBody . "&signature=" . $signature;
|
$res = [
|
'url' => $ss_url,
|
'raw' => $raw,
|
'signatureBody' => $signatureBody
|
];
|
echo_dhklog($res, '构建重定向URL:', 'worldfirst_pay');
|
return dhkSuccess($res);
|
//5、重定向到URL
|
return redirect($ss_url);
|
}
|
//接收授权
|
public function getAuth()
|
{
|
$params = Request::param();
|
echo_dhklog($params, '授权回调data:', 'worldfirst_pay');
|
return dhkSuccess($params, '接收授权成功,等待处理....');
|
}
|
//查询支付状态http://zhc.test.com/home/testpay/query?pay_code=202504171234234
|
public function query()
|
{
|
$params = Request::param();
|
$payToRequestId = $params['pay_code'] ?? ''; //商户生成的支付单号
|
$payToId = $params['payToId'] ?? ''; //万里汇生成的支付单号
|
if (!$payToRequestId and !$payToId) {
|
return dhkMsg('支付单号不能为空');
|
}
|
$post_data = [];
|
if ($payToRequestId) {
|
$payToRequestIds = [$payToRequestId];
|
$post_data['payToRequestIds'] = $payToRequestIds;
|
}
|
if ($payToId) {
|
$payToIds = [$payToId];
|
$post_data['payToIds'] = $payToIds;
|
}
|
$requestTime = date('Y-m-d\TH:i:sP');
|
$httpMethod = 'POST'; // 请求方法(GET/POST等)
|
|
$api_url = '/amsin/api/v1/business/inquiryPayOrder'; //支付完成后,集成商可以使用此接口来查询支付结果。
|
$signatureBody = $this->getSignatureBody($post_data, $httpMethod, $api_url, $requestTime);
|
// 包裹私钥
|
$privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($this->config['privateKey'], 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----";
|
|
// 生成签名
|
$signature = $this->generateSignature($signatureBody, $privateKey);
|
$post_url = $this->config['domain'] . $api_url;
|
$header = [];
|
$clientId = $this->config['is_sandbox'] == 1 ? 'SANDBOX_' . $this->config['ClientID'] : $this->config['ClientID'];
|
$header['client-id'] = $clientId;
|
$header['request-time'] = $requestTime;
|
$header['Content-Type'] = 'application/json';
|
$header['signature'] = 'algorithm=RSA256,keyVersion=1,signature=' . $signature;
|
$dhkhttp = new \app\common\toole\Dhkhttp();
|
$res = $dhkhttp->dhkpost($post_url, $post_data, $header);
|
return dhkSuccess($res);
|
}
|
public function notify()
|
{
|
$params = Request::param();
|
echo_dhklog($params, '支付通知data:', 'worldfirst_pay');
|
$headers = Request::header();
|
echo_dhklog($headers, '支付通知header:', 'worldfirst_pay');
|
$requestTime = $headers['request-time'] ?? ''; //请求时间
|
$signature = $headers['signature'] ?? ''; //签名
|
//algorithm=RSA256,keyVersion=1,signature=IHZfFMPNQITqmz%2FDZTlm6DEfm6yfR3NtK0LkONscZxZLqOuCa5b%2FDyLGqwZaSrGIQeFFNnGS5EgqRtFFdOmBSuSSiwK%2BjvhnIE6qHP7xr%2BjBpjFFztTOyyniGJdN5HlT8UE2wONjPIsIMh8koXa6Kb8uh1ScnCGbTzY8ogfihupFXJt%2B1%2BHPYno9483cVyA2l9UOYb6ai6SWgAxnJJUWi%2BkBQLXp%2FzvRG6SmDETbZ8MpMM2gUTbRGB4p4eSqVcX6KgwVyLSgrzAGekPv6dkZOH5zulHCv%2FmMXdO3%2FWmQn%2FX2rS1unS9yilDJbzDW86XwUf46UD2qgxkFGi6UPWaTfw%3D%3D
|
//从$signature中提取signature=后面的内容
|
$signature = str_replace('algorithm=RSA256,keyVersion=1,signature=', '', $signature);
|
echo_dhklog($signature, 'HEADER签名', 'worldfirst_pay');
|
|
|
$clientId = $headers['client-id'] ?? '';
|
$httpMethod = 'POST';
|
$api_url = '/home/testpay/notify';
|
// 包裹私钥
|
$privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($this->config['privateKey'], 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----";
|
|
$res = ["result" => ["resultStatus" => "S", "resultCode" => "SUCCESS", "resultMessage" => "success"]];
|
$signatureBody = $this->getSignatureBody($params, $httpMethod, $api_url, $requestTime);
|
// 生成签名
|
$signature_new = $this->generateSignature($signatureBody, $privateKey);
|
if ($signature_new != $signature) {
|
echo_dhklog($signature_new, '签名不匹配', 'worldfirst_pay');
|
} else {
|
echo_dhklog('验证通过', '签名匹配', 'worldfirst_pay');
|
}
|
//返回响应头
|
header('Content-Type: application/json');
|
header('client-id: ' . $clientId);
|
header('request-time: ' . $requestTime);
|
header('signature: algorithm=RSA256,keyVersion=1,signature=' . $signature_new);
|
return json($res);
|
}
|
|
//1. 构造待签名字符串(与JavaScript逻辑完全一致)
|
public function getSignatureBody($post_data = [], $httpMethod = 'POST', $api_url = '', $requestTime = '')
|
{
|
$bodyData = json_encode($post_data);
|
$clientId = $this->config['is_sandbox'] == 1 ? 'SANDBOX_' . $this->config['ClientID'] : $this->config['ClientID'];
|
$signatureBody = sprintf(
|
"%s %s\n%s.%s.%s",
|
strtoupper($httpMethod),
|
$api_url,
|
$clientId,
|
$requestTime,
|
$bodyData
|
);
|
return $signatureBody;
|
}
|
/**
|
* 生成签名
|
* @param string $clientId 商户ID
|
* @param string $requestTime 请求时间戳
|
* @param string $httpMethod HTTP方法(GET/POST等)
|
* @param string $api 请求API路径
|
* @param string $bodyData 请求体JSON字符串
|
* @param string $privateKey 私钥(PEM格式)
|
* @return string 返回URL编码后的签名
|
*/
|
public static function generateSignature($signatureBody, $privateKey): string
|
{
|
// 2. 使用私钥进行SHA256签名
|
$signature = '';
|
if (!openssl_sign($signatureBody, $signature, $privateKey, OPENSSL_ALGO_SHA256)) {
|
// 输出错误信息
|
echo_dhklog(openssl_error_string(), 'OpenSSL错误', 'worldfirst_pay');
|
return '';
|
}
|
// 3. Base64编码签名
|
$ss = base64_encode($signature);
|
echo_dhklog($ss, '签名', 'worldfirst_pay');
|
// 4. URL编码签名,非必要
|
$ss = urlencode($ss);
|
return $ss;
|
}
|
|
/**
|
* 验证签名(可选)
|
*/
|
public static function verifySignature(
|
string $plainText,
|
string $signature,
|
string $publicKey
|
): bool {
|
$signature = base64_decode(urldecode($signature));
|
return (bool)openssl_verify(
|
$plainText,
|
$signature,
|
$publicKey,
|
OPENSSL_ALGO_SHA256
|
);
|
}
|
|
//账单查询API--列表ok
|
public function inquiryStatementList()
|
{
|
//uzzyName字段取值为空时,startTime 和 endTime 计算的账单时长不得超过3个月(100天)。
|
$nowdate = date('Y-m-d\TH:i:sP');
|
$nowtime = time();
|
$starttime = strtotime('-3 month', $nowtime); //3个月前时间戳
|
$endtime = strtotime('-1 month', $nowtime); //现在时间戳
|
$post_data = [
|
"startTime" => date('Y-m-d\TH:i:sP', $starttime), //开始时间,格式为ISO 8601
|
"endTime" => date('Y-m-d\TH:i:sP', $endtime), //结束时间,格式为ISO 8601
|
"pageSize" => 10, //每页大小,最大为100
|
"pageNumber" => 1, //页码,从1开始
|
"transactionTypeList" => [], //交易类型列表,可选,不传则查询所有类型
|
"currencyList" => [], //币种列表,可选,不传则查询所有币种
|
"fuzzyName" => "" //模糊查询字段,可选,不传则不进行模糊查询
|
];
|
$requestTime = $nowdate;
|
$httpMethod = 'POST'; // 请求方法(GET/POST等)
|
|
$api_url = '/amsin/api/v1/business/account/inquiryStatementList'; //支付完成后,集成商可以使用此接口来查询支付结果。
|
$signatureBody = $this->getSignatureBody($post_data, $httpMethod, $api_url, $requestTime);
|
// 包裹私钥
|
$privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($this->config['privateKey'], 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----";
|
|
// 生成签名
|
$signature = $this->generateSignature($signatureBody, $privateKey);
|
$post_url = $this->config['domain'] . $api_url;
|
$header = [];
|
$clientId = $this->config['is_sandbox'] == 1 ? 'SANDBOX_' . $this->config['ClientID'] : $this->config['ClientID'];
|
$header['client-id'] = $clientId;
|
$header['request-time'] = $requestTime;
|
$header['Content-Type'] = 'application/json';
|
$header['signature'] = 'algorithm=RSA256,keyVersion=1,signature=' . $signature;
|
$dhkhttp = new \app\common\toole\Dhkhttp();
|
echo_dhklog($api_url, '请求地址:', 'worldfirst_pay');
|
$apidata = $dhkhttp->dhkpost($post_url, $post_data, $header);
|
if ($apidata['http_code'] != 200) {
|
$msg = $apidata['msg'] ?? '接口请求失败';
|
return dhkMsg($msg);
|
}
|
$api_result = $apidata['result'];
|
if ($api_result['resultStatus'] != 'S') {
|
return dhkMsg($api_result['resultMessage']);
|
}
|
$totalCount = $apidata['totalCount']; //总条数
|
if ($totalCount == 0) {
|
return dhkMsg('暂无账单');
|
}
|
$totalPageNumber = $apidata['totalPageNumber']; //总页数
|
$currentPageNumber = $apidata['currentPageNumber']; //当前页码
|
$list = $apidata['statementList']; //账单列表
|
$res = [
|
'totalCount' => $totalCount, //总条数
|
'totalPageNumber' => $totalPageNumber, //总页数
|
'currentPageNumber' => $currentPageNumber, //当前页码
|
'list' => $list, //账单列表
|
];
|
return dhkSuccess($res);
|
}
|
//帐单详情API--ok
|
public function inquiryStatementDetail()
|
{
|
$bno = Request::param('bno');
|
$post_data = [
|
"accountingBizNo" => $bno //万里汇账单动账流水单号,由万里汇生成,用于查询账单详情
|
];
|
$requestTime = date('Y-m-d\TH:i:sP');
|
$httpMethod = 'POST'; // 请求方法(GET/POST等)
|
$api_url = '/amsin/api/v1/business/account/inquiryStatementDetail'; //支付完成后,集成商可以使用此接口来查询支付结果。
|
$post_url = $this->config['domain'] . $api_url;
|
$header = $this->getHeaderData($post_data, $httpMethod, $api_url, $requestTime);
|
$dhkhttp = new \app\common\toole\Dhkhttp();
|
echo_dhklog($api_url, '请求地址:', 'worldfirst_pay');
|
$apidata = $dhkhttp->dhkpost($post_url, $post_data, $header);
|
if ($apidata['http_code'] != 200) {
|
$msg = $apidata['msg'] ?? '接口请求失败';
|
return dhkMsg($msg);
|
}
|
$api_result = $apidata['result'];
|
if ($api_result['resultStatus'] != 'S') {
|
return dhkMsg($api_result['resultMessage']);
|
}
|
return dhkSuccess($apidata);
|
}
|
//余额查询API--
|
public function inquiryBalance()
|
{
|
$post_data = [
|
"currencyList" => [], //币种列表,为 ISO 4217 标准规定的三位字母货币代码,为空时,则会响应所有币种的余额信息
|
"balanceTypes" => [] //余额类型列表,可选,不传则查询所有类型,当该字段为空时,NORMAL_BALANCE为默认取值。
|
//NORMAL_BALANCE: 普通余额类型(即电商余额类型)。(默认);SAME_NAME_TOP_UP_BALANCE: 同名充值余额类型。
|
];
|
$requestTime = date('Y-m-d\TH:i:sP');
|
$httpMethod = 'POST'; // 请求方法(GET/POST等)
|
$api_url = '/amsin/api/v1/business/account/inquiryBalance'; //支付完成后,集成商可以使用此接口来查询支付结果。
|
$post_url = $this->config['domain'] . $api_url;
|
$header = $this->getHeaderData($post_data, $httpMethod, $api_url, $requestTime);
|
$dhkhttp = new \app\common\toole\Dhkhttp();
|
echo_dhklog($api_url, '请求地址:', 'worldfirst_pay');
|
$apidata = $dhkhttp->dhkpost($post_url, $post_data, $header);
|
if ($apidata['http_code'] != 200) {
|
$msg = $apidata['msg'] ?? '接口请求失败';
|
return dhkMsg($msg);
|
}
|
$api_result = $apidata['result'];
|
if ($api_result['resultStatus'] != 'S') {
|
return dhkMsg($api_result['resultMessage']);
|
}
|
$accountBalances = $apidata['accountBalances']; //用户的账户信息列表,包括账号、账户币种、账户余额等信息。
|
//accountNo万里汇定义的唯一账户ID
|
return dhkSuccess($apidata);
|
}
|
//获取万里汇主账号和子账号的信息
|
public function inquiryAccountInfo()
|
{
|
$post_data = [
|
"pageSize" => 20, //每页包含的条目数
|
"pageNumber" => 1 //当前页码
|
];
|
$requestTime = date('Y-m-d\TH:i:sP');
|
$httpMethod = 'POST'; // 请求方法(GET/POST等)
|
$api_url = '/amsin/api/v1/business/user/inquirySubuser'; //支付完成后,集成商可以使用此接口来查询支付结果。
|
$post_url = $this->config['domain'] . $api_url;
|
$header = $this->getHeaderData($post_data, $httpMethod, $api_url, $requestTime);
|
$dhkhttp = new \app\common\toole\Dhkhttp();
|
echo_dhklog($api_url, '请求地址:', 'worldfirst_pay');
|
$apidata = $dhkhttp->dhkpost($post_url, $post_data, $header);
|
if ($apidata['http_code'] != 200) {
|
$msg = $apidata['msg'] ?? '接口请求失败';
|
return dhkMsg($msg);
|
}
|
$api_result = $apidata['result'];
|
if ($api_result['resultStatus'] != 'S') {
|
return dhkMsg($api_result['resultMessage']);
|
}
|
$totalCount = $apidata['totalCount']; //总条数
|
if ($totalCount == 0) {
|
return dhkMsg('暂无账单');
|
}
|
$totalPageNumber = $apidata['totalPageNumber']; //总页数
|
$currentPageNumber = $apidata['currentPageNumber']; //当前页码
|
$primaryUserInformation = $apidata['primaryUserInformation']; //主账号信息
|
$userInformations = $apidata['userInformations']; //子账号信息
|
$list = $apidata['statementList']; //账单列表
|
$res = [
|
'totalCount' => $totalCount, //总条数
|
'totalPageNumber' => $totalPageNumber, //总页数
|
'currentPageNumber' => $currentPageNumber, //当前页码
|
'primaryUserInformation' => $primaryUserInformation, //主账号信息
|
'userInformations' => $userInformations, //子账号信息
|
];
|
return dhkSuccess($apidata);
|
}
|
//店铺管理API--获取店铺信息以及店铺关联账号的信息
|
public function inquiryStore()
|
{
|
$post_data = [
|
"pageSize" => 100, //每页包含的条目数
|
"pageNumber" => 1 //当前页码
|
];
|
$requestTime = date('Y-m-d\TH:i:sP');
|
$httpMethod = 'POST'; // 请求方法(GET/POST等)
|
$api_url = '/amsin/api/v1/business/store/inquiryStore'; //支付完成后,集成商可以使用此接口来查询支付结果。
|
$post_url = $this->config['domain'] . $api_url;
|
$header = $this->getHeaderData($post_data, $httpMethod, $api_url, $requestTime);
|
$dhkhttp = new \app\common\toole\Dhkhttp();
|
echo_dhklog($api_url, '请求地址:', 'worldfirst_pay');
|
$apidata = $dhkhttp->dhkpost($post_url, $post_data, $header);
|
if ($apidata['http_code'] != 200) {
|
$msg = $apidata['msg'] ?? '接口请求失败';
|
return dhkMsg($msg);
|
}
|
$api_result = $apidata['result'];
|
if ($api_result['resultStatus'] != 'S') {
|
return dhkMsg($api_result['resultMessage']);
|
}
|
$totalCount = $apidata['totalCount']; //总条数
|
if ($totalCount == 0) {
|
return dhkMsg('暂无账单');
|
}
|
$totalPageNumber = $apidata['totalPageNumber']; //总页数
|
$currentPageNumber = $apidata['currentPageNumber']; //当前页码
|
$storeInformation = $apidata['storeInformation']; //storeInformation
|
$res = [
|
'totalCount' => $totalCount, //总条数
|
'totalPageNumber' => $totalPageNumber, //总页数
|
'currentPageNumber' => $currentPageNumber, //当前页码
|
'storeInformation' => $storeInformation,
|
];
|
return dhkSuccess($apidata);
|
}
|
//结汇额度查询API--帐户管理
|
public function inquiryAvailableQuota()
|
{
|
$post_data = [
|
"quotaAccumulationMethod" => "USER_ID",
|
//结汇额度的累计方式
|
//可取值如下:USER_ID :根据申报主体UID(即已入驻万里汇的用户ID)累积申报额度。标识传入交易卖家的用户ID
|
//RECEIVING_ACCOUNT :根据收款账户(RA)累计申报额度。标识传入交易卖家的收款账户(RA)号
|
//VIRTUAL_ACCOUNT:根据虚拟账户(VA)累计申报额度。标识传入交易卖家的虚拟账户(VA)号
|
//BENEFICIARY:根据收款人(即未入驻万里汇的外部平台用户)累计申报额度。标识传入外部平台的用户ID
|
"quotaAccumulationId" => "2193110014766029", //结汇额度累计方式的标识
|
"currency" => 'USD', //结汇额度的币种。 币种必须满足ISO 4217 标准,比如 "USD" 。
|
//"tradeType" => "ALL", //贸易类型。可取值如下:GOODS:货物贸易,SERVICE:服务贸易。当 quotaAccumulationMethod = BENEFICIARY时,此字段为必传。
|
];
|
$requestTime = date('Y-m-d\TH:i:sP');
|
$httpMethod = 'POST'; // 请求方法(GET/POST等)
|
$api_url = '/amsin/api/v1/business/account/inquiryAvailableQuota'; //支付完成后,集成商可以使用此接口来查询支付结果。
|
$post_url = $this->config['domain'] . $api_url;
|
$header = $this->getHeaderData($post_data, $httpMethod, $api_url, $requestTime);
|
$dhkhttp = new \app\common\toole\Dhkhttp();
|
echo_dhklog($api_url, '请求地址:', 'worldfirst_pay');
|
$apidata = $dhkhttp->dhkpost($post_url, $post_data, $header);
|
if ($apidata['http_code'] != 200) {
|
$msg = $apidata['msg'] ?? '接口请求失败';
|
return dhkMsg($msg);
|
}
|
$api_result = $apidata['result'];
|
if ($api_result['resultStatus'] != 'S') {
|
return dhkMsg($api_result['resultMessage']);
|
}
|
$availableQuota = $apidata['availableQuota']; //可申报的结汇额度。
|
return dhkSuccess($apidata);
|
}
|
//独立站平台标识INDEPENDENT_SITE
|
//上传交易信息累计额度API--未对接
|
public function uploadTransactionInfo()
|
{
|
$post_data = [
|
"quotaAccumulationMethod" => "USER_ID",
|
//结汇额度的累计方式
|
//可取值如下:USER_ID :根据申报主体UID(即已入驻万里汇的用户ID)累积申报额度。标识传入交易卖家的用户ID
|
//RECEIVING_ACCOUNT :根据收款账户(RA)累计申报额度。标识传入交易卖家的收款账户(RA)号
|
//VIRTUAL_ACCOUNT:根据虚拟账户(VA)累计申报额度。标识传入交易卖家的虚拟账户(VA)号
|
//BENEFICIARY:根据收款人(即未入驻万里汇的外部平台用户)累计申报额度。标识传入外部平台的用户ID
|
"quotaAccumulationId" => "2193110014766029", //结汇额度累计方式的标识
|
"currency" => 'USD', //结汇额度的币种。 币种必须满足ISO 4217 标准,比如 "USD" 。
|
//"tradeType" => "ALL", //贸易类型。可取值如下:GOODS:货物贸易,SERVICE:服务贸易。当 quotaAccumulationMethod = BENEFICIARY时,此字段为必传。
|
];
|
$requestTime = date('Y-m-d\TH:i:sP');
|
$httpMethod = 'POST'; // 请求方法(GET/POST等)
|
$api_url = '/amsin/api/v1/business/account/submitTradeOrder'; //支付完成后,集成商可以使用此接口来查询支付结果。
|
$post_url = $this->config['domain'] . $api_url;
|
$header = $this->getHeaderData($post_data, $httpMethod, $api_url, $requestTime);
|
$dhkhttp = new \app\common\toole\Dhkhttp();
|
echo_dhklog($api_url, '请求地址:', 'worldfirst_pay');
|
$apidata = $dhkhttp->dhkpost($post_url, $post_data, $header);
|
if ($apidata['http_code'] != 200) {
|
$msg = $apidata['msg'] ?? '接口请求失败';
|
return dhkMsg($msg);
|
}
|
$api_result = $apidata['result'];
|
if ($api_result['resultStatus'] != 'S') {
|
return dhkMsg($api_result['resultMessage']);
|
}
|
$availableQuota = $apidata['availableQuota']; //可申报的结汇额度。
|
return dhkSuccess($apidata);
|
}
|
//获取转账相关信息API--转帐前1
|
public function fund_consultPayout()
|
{
|
//转帐金额
|
$transferFromAmount = $this->getCurrenyMoneytoMinorUnit(100, 'USD');
|
$post_data = [
|
"transferFromDetail" => [
|
"transferFromAmount" => [
|
"currency" => "USD",
|
"value" => $transferFromAmount,
|
],
|
],
|
//转账业务类型码。当 transferToDetail . transferToAmount . currency = CNY 时,此字段为必传。
|
//THIRD_PARTY_PAYOUT:转账到第三方卡。第三方卡包括企业卡和个人卡。SAME_NAME_PAYOUT:提现到同名卡
|
"businessSceneCode" => "THIRD_PARTY_PAYOUT",
|
"transferToDetail" => [
|
"transferToMethod" => [
|
"paymentMethodMetaData" => [
|
"bankLocalName" => "xxxxxxx",
|
"bankCountryCode" => "CN",
|
"bankAccountLocalName" => "xxxxxxx",
|
"beneficiaryType" => "THIRD_PARTY_PERSONAL_BANK_ACCOUNT",
|
"bankAccountNo" => "xxxxxxxxxxxx"
|
],
|
"paymentMethodType" => "BANK_ACCOUNT_DETAIL"
|
],
|
"transferToAmount" => [
|
"currency" => "CNY",
|
"value" => 100,
|
]
|
]
|
];
|
$requestTime = date('Y-m-d\TH:i:sP');
|
$httpMethod = 'POST'; // 请求方法(GET/POST等)
|
$api_url = '/amsin/api/v1/business/fund/consultPayout'; //支付完成后,集成商可以使用此接口来查询支付结果。
|
$post_url = $this->config['domain'] . $api_url;
|
$header = $this->getHeaderData($post_data, $httpMethod, $api_url, $requestTime);
|
$dhkhttp = new \app\common\toole\Dhkhttp();
|
echo_dhklog($api_url, '请求地址:', 'worldfirst_pay');
|
$apidata = $dhkhttp->dhkpost($post_url, $post_data, $header);
|
if ($apidata['http_code'] != 200) {
|
$msg = $apidata['msg'] ?? '接口请求失败';
|
return dhkMsg($msg);
|
}
|
$api_result = $apidata['result'];
|
if ($api_result['resultStatus'] != 'S') {
|
return dhkMsg($api_result['resultMessage']);
|
}
|
$availableQuota = $apidata['availableQuota']; //可申报的结汇额度。
|
return dhkSuccess($apidata);
|
}
|
//获取请求头及签名
|
public function getHeaderData($post_data = [], $httpMethod = 'POST', $api_url = '', $requestTime = '')
|
{
|
if ($requestTime == '') {
|
$requestTime = date('Y-m-d\TH:i:sP');
|
}
|
$signatureBody = $this->getSignatureBody($post_data, $httpMethod, $api_url, $requestTime);
|
// 包裹私钥
|
$privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($this->config['privateKey'], 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----";
|
|
// 生成签名
|
$signature = $this->generateSignature($signatureBody, $privateKey);
|
$post_url = $this->config['domain'] . $api_url;
|
$header = [];
|
$clientId = $this->config['is_sandbox'] == 1 ? 'SANDBOX_' . $this->config['ClientID'] : $this->config['ClientID'];
|
$header['client-id'] = $clientId;
|
$header['request-time'] = $requestTime;
|
$header['Content-Type'] = 'application/json';
|
$header['signature'] = 'algorithm=RSA256,keyVersion=1,signature=' . $signature;
|
return $header;
|
}
|
}
|