跳到主要内容

PHP 示例

完整的 PHP 集成示例,使用原生 cURL,无第三方 SDK。

配置

# .env
API_BASE=https://api.168tonpay.xyz/api/v1/compat/godapay
APPLY_BASE=https://apply.168tonpay.xyz/api/v1/compat/godapay
MERCHANT_ID=aef6025b-f435-443c-bb18-f10e65d9314c
API_SECRET=...

签名工具

<?php
// gateway/auth.php

/**
* GodaPay 兼容 MD5 排序签名。
* 排除 signature 与 null,按 key 升序拼接,追加 &key=SECRET,MD5 小写十六进制。
*/
function gateway_sign(array $params, string $apiSecret): string {
$filtered = array_filter(
$params,
fn($v, $k) => $k !== 'signature' && $v !== null,
ARRAY_FILTER_USE_BOTH
);
ksort($filtered);
$pairs = [];
foreach ($filtered as $k => $v) {
$pairs[] = "$k=" . (is_bool($v) ? ($v ? 'true' : 'false') : $v);
}
$signStr = implode('&', $pairs) . '&key=' . $apiSecret;
return strtolower(md5($signStr));
}

API 客户端

<?php
// gateway/client.php
require_once __DIR__ . '/auth.php';

class GatewayException extends Exception {
public $businessCode;
public function __construct($code, $message) {
parent::__construct($message);
$this->businessCode = $code;
}
}

function gateway_post(string $base, string $path, array $params) {
$params['signature'] = gateway_sign($params, getenv('API_SECRET'));
$bodyString = json_encode($params, JSON_UNESCAPED_SLASHES);

$ch = curl_init($base . $path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => $bodyString,
]);
$response = curl_exec($ch);
if ($response === false) {
throw new RuntimeException('curl error: ' . curl_error($ch));
}
curl_close($ch);

$json = json_decode($response, true);
if (!$json || ($json['code'] ?? -1) !== 0) {
throw new GatewayException($json['code'] ?? 0, $json['message'] ?? 'Unknown error');
}
return $json['data'];
}

创建收款订单

<?php
require_once __DIR__ . '/gateway/client.php';

function start_deposit($player, $orderNo) {
$order = gateway_post(getenv('API_BASE'), '/pay/order/create', [
'merchantId' => getenv('MERCHANT_ID'),
'orderNo' => $orderNo,
'returnUrl' => 'https://yourgame.com/api/webhooks/payment',
'playerPhone' => $player['phone'],
'playerRef' => $player['id'],
]);

return [
'payUrl' => $order['payUrl'],
'platformOrderNo' => $order['platformOrderNo'],
];
}

创建付款订单

<?php
function start_withdrawal($player, $outOrderNo, $amount) {
return gateway_post(getenv('APPLY_BASE'), '/apply/create', [
'merchantId' => getenv('MERCHANT_ID'),
'outOrderNo' => $outOrderNo,
'amount' => number_format($amount, 2, '.', ''),
'bankType' => 'BKASH',
'userName' => $player['name'],
'account' => $player['phone'],
'returnUrl' => 'https://yourgame.com/api/webhooks/payout',
]);
}

Webhook 处理

<?php
// webhook.php —— webhook 是 form-urlencoded
require_once __DIR__ . '/gateway/auth.php';

$fields = $_POST; // application/x-www-form-urlencoded
$signature = $fields['signature'] ?? '';
unset($fields['signature']);

if (!hash_equals(gateway_sign($fields, getenv('API_SECRET')), $signature)) {
http_response_code(401);
echo 'invalid signature';
exit;
}

if (($_POST['status'] ?? '') === '1') {
// 幂等:用 platformOrderNo 去重;用 amount 上分
credit_player($_POST['orderNo'], $_POST['amount']);
}

echo 'SUCCESS'; // 必须应答字面量 SUCCESS

错误处理

<?php
try {
$order = gateway_post(getenv('API_BASE'), '/pay/order/create', $data);
} catch (GatewayException $e) {
// businessCode 非 0 即业务错误
throw new RuntimeException("[{$e->businessCode}] " . $e->getMessage());
}

下一步