跳转到内容

PHP 示例

此示例基于 Laravel HTTP Client,包含签名、POST JSONGET Query,以及代收下单、代付下单、商户信息查询三个接口。

php
<?php

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

final class SkynetClient
{
    public function __construct(
        private readonly string $baseUrl,
        private readonly int $mchId,
        private readonly string $apiToken,
    ) {}

    public function createCollectOrder(): array
    {
        return $this->post('/api/v1/mch/pmt-orders', [
            'trans_id' => 'ORDER-' . time(),
            'currency' => 'VND',
            'amount' => '100.00',
            'channel' => 'bank',
            'callback_url' => 'https://merchant.example.com/callback/collect',
            'return_url' => 'https://merchant.example.com/payment/result',
            'remarks' => 'collect demo',
        ]);
    }

    public function createPayoutOrder(): array
    {
        return $this->post('/api/v1/mch/wdl-orders', [
            'trans_id' => 'WDL-' . time(),
            'channel' => 'bank',
            'amount' => '100.00',
            'currency' => 'VND',
            'account_no' => '2333667799212341',
            'account_name' => 'NGUYEN XUAN HUNG',
            'account_org' => 'PVCOMBANK',
            'account_org_code' => '970412',
            'callback_url' => 'https://merchant.example.com/callback/payout',
            'remarks' => 'payout demo',
        ]);
    }

    public function getMerchantInfo(): array
    {
        return $this->get('/api/v1/mch/info');
    }

    private function post(string $path, array $params): array
    {
        $params = $this->withSignature($params);
        $response = Http::timeout(10)
            ->asJson()
            ->post($this->baseUrl . $path, $params);

        return $this->parseResponse($response->status(), $response->json());
    }

    private function get(string $path, array $params = []): array
    {
        $params = $this->withSignature($params);
        $response = Http::timeout(10)->get($this->baseUrl . $path, $params);

        return $this->parseResponse($response->status(), $response->json());
    }

    private function withSignature(array $params): array
    {
        $params['mch_id'] = $this->mchId;
        $params['nonce'] = Str::random(12);
        $params['timestamp'] = time();
        $params['sign'] = $this->sign($params);

        return $params;
    }

    private function sign(array $params): string
    {
        unset($params['sign']);
        ksort($params, SORT_STRING);

        $source = $this->apiToken;
        foreach ($params as $key => $value) {
            if ($value === null || $value === '') {
                continue;
            }

            $source .= '&' . $key . '=' . $value;
        }

        return md5($source);
    }

    private function parseResponse(int $httpStatus, ?array $body): array
    {
        if ($httpStatus < 200 || $httpStatus >= 300) {
            throw new RuntimeException('HTTP request failed: ' . $httpStatus);
        }

        if (!is_array($body) || ($body['code'] ?? null) !== 200) {
            $message = $body['errors']['message'] ?? $body['message'] ?? 'API request failed';
            throw new RuntimeException($message);
        }

        return $body['payload'] ?? [];
    }
}

$client = new SkynetClient(
    baseUrl: 'https://api.example.com',
    mchId: 10001,
    apiToken: 'demo_key_123456',
);

$collectOrder = $client->createCollectOrder();
$payoutOrder = $client->createPayoutOrder();
$merchantInfo = $client->getMerchantInfo();

Released under the MIT License.