PHP code example of goletter / hyperf-card

1. Go to this page and download the library: Download goletter/hyperf-card library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

goletter / hyperf-card example snippets


use Goletter\Card\CardFactory;
use Goletter\Card\Platforms\Slash\Exceptions\SlashApiException;

$config = [
    'base_url' => 'https://api.slash.com',   // 也可用 baseUrl
    'api_key'  => 'your-api-key',            // 也可用 apiKey
    'timeout'  => 60,
    // 可选:敏感信息解密
    // 'rsa_public_key' => '...',
    // 'private_key' => file_get_contents('/secure/slash-private.pem'),
    // 'vault_base_url' => 'https://vault.slash.com',
    // 可选:更新限额时的商户白名单
    // 'merchant_allowlist' => ['merchant_v2_xxx'],
];

// ① 命名方法(IDE 提示最好)
$bundle = CardFactory::slash($config);

// ② 字符串平台名
$bundle = CardFactory::make('slash', $config);

// ③ 数字别名(与 publish/card.php 中 platforms 映射一致,默认 1 = slash)
$bundle = CardFactory::make(1, $config);

$adapter = $bundle->adapter(); // Slash\Adapter\CardAdapter

try {
    // 返回 {code, msg, data}
    $page = $adapter->cardList([
        'cursor' => '',   // 首页传空;下一页用上一页 data.cursor
    ]);

    if ($page['code'] !== 1) {
        throw new \RuntimeException($page['msg'] ?? 'list failed');
    }

    foreach ($page['data']['data'] ?? [] as $card) {
        // ...
    }

    $info = $adapter->cardInfo(['card_id' => 'card_xxx']);
    $adapter->cardFreeze(['card_id' => 'card_xxx']);
    $adapter->cardUnfreeze(['card_id' => 'card_xxx']);
    $adapter->cardCancel(['card_id' => 'card_xxx']);
} catch (SlashApiException $e) {
    echo $e->getMessage();
    print_r($e->getResponse());
}

$adapter = $bundle->adapter();
$allCards = [];
$cursor = '';

do {
    $page = $adapter->listCardsPaginated($cursor === '' ? null : $cursor);
    if ($page['code'] !== 1) {
        break;
    }
    $allCards = array_merge($allCards, $page['data']['data'] ?? []);
    $cursor = (string) ($page['data']['cursor'] ?? '');
} while ($cursor !== '');

$api = $bundle->card(); // 等同 $bundle->api()

// 原始 Slash JSON;失败直接抛 SlashApiException
$raw = $api->listCards(['cursor' => '', 'sort' => 'createdAt', 'sortDirection' => 'DESC']);
$detail = $api->getCard('card_xxx', ['

'slash' => [
    'base_url' => env('SLASH_BASE_URL', 'https://api.slash.com'),
    'api_key' => env('SLASH_API_KEY', ''),
    'timeout' => 60,
    // 'rsa_public_key' => env('SLASH_RSA_PUBLIC_KEY', ''),
    // 'private_key' => env('SLASH_PRIVATE_KEY', ''),
    // 'vault_base_url' => env('SLASH_VAULT_URL', ''),
    // 'merchant_allowlist' => [],
],

use Goletter\Card\CardFactory;
use Hyperf\Di\Annotation\Inject;

class CardService
{
    #[Inject]
    protected CardFactory $cardFactory;

    public function listSlashCards(?string $cursor = null): array
    {
        // 读取 config/autoload/card.php 的 slash 配置
        $bundle = $this->cardFactory->create('slash');

        // 临时覆盖(例如切换账号 api_key)
        // $bundle = $this->cardFactory->create('slash', ['api_key' => $otherKey]);

        // 业务统一字段 → adapter();官方原始 JSON → card()/api()
        return $bundle->adapter()->cardList([
            'cursor' => $cursor ?? '',
        ]);
    }
}

$factory = new CardFactory(ctory);

$bundle = CardFactory::slash(); // 使用配置文件中的 slash 段

use Goletter\Card\Contract\TokenPersisterInterface;

$bundle = CardFactory::airwallex([
    'api_key' => '...',
    'client_id' => '...',
    'card_accounts_id' => 1,
    'token_persister' => $container->get(TokenPersisterInterface::class),
    // 或:'token_persister' => fn ($accountId, array $token) => { ... },
]);

use Goletter\Card\Platforms\Airwallex\Airwallex;

$airwallex = new Airwallex([
    'baseUrl' => 'https://api-demo.airwallex.com',  // API 基础地址
    'apiKey' => 'your-api-key',                      // API Key
    'clientId' => 'your-client-id',                  // Client ID
    'timeout' => 60,                                 // 请求超时时间(秒)
    'requestSource' => 4,                            // 请求来源标识
]);

// 自动获取并管理 token
$result = $airwallex->authentication()->login();

// 返回结果包含 token
// $result['token']

$cards = $airwallex->card()->listCards([
    'page_num' => 0,      // 页码,从 0 开始
    'page_size' => 10,    // 每页数量
]);

// 返回卡片列表数据

$cardId = 'd467705b-6ef1-42b0-8b67-aa74caaa6b06';
$cardDetails = $airwallex->card()->getCardDetails($cardId);

$cardId = 'd467705b-6ef1-42b0-8b67-aa74caaa6b06';
$limits = $airwallex->card()->getCardLimits($cardId);

$newCard = $airwallex->card()->createCard([
    // 卡片创建所需的数据
    // 具体字段请参考 Airwallex API 文档
]);

$cardId = 'd467705b-6ef1-42b0-8b67-aa74caaa6b06';
$updatedCard = $airwallex->card()->updateCard($cardId, [
    // 需要更新的字段
]);

$cardId = 'd467705b-6ef1-42b0-8b67-aa74caaa6b06';
$result = $airwallex->card()->freezeCard($cardId, [
    // 可选:冻结原因等数据
]);

$cardId = 'd467705b-6ef1-42b0-8b67-aa74caaa6b06';
$result = $airwallex->card()->unfreezeCard($cardId, [
    // 可选:解冻原因等数据
]);

$cardId = 'd467705b-6ef1-42b0-8b67-aa74caaa6b06';
$result = $airwallex->card()->cancelCard($cardId, [
    // 可选:取消原因等数据
]);

$airwallex->setAccessToken('your-token', $expiresAt); // $expiresAt 为可选的过期时间戳

use Goletter\Card\Platforms\Airwallex\Exceptions\AirwallexApiException;
use Goletter\Card\Platforms\Airwallex\Exceptions\AirwallexTokenExpiredException;

try {
    $cards = $airwallex->card()->listCards();
} catch (AirwallexTokenExpiredException $e) {
    // Token 过期,SDK 会自动重新获取,但也可以手动处理
    echo "Token expired: " . $e->getMessage();
} catch (AirwallexApiException $e) {
    // 其他 API 错误
    echo "API Error: " . $e->getMessage();
    $response = $e->getResponse(); // 获取错误响应数据
}



use Goletter\Card\Platforms\Airwallex\Airwallex;
use Goletter\Card\Platforms\Airwallex\Exceptions\AirwallexApiException;

// 初始化
$airwallex = new Airwallex([
    'baseUrl' => 'https://api-demo.airwallex.com',
    'apiKey' => 'your-api-key',
    'clientId' => 'your-client-id',
]);

try {
    // 登录(可选,SDK 会在需要时自动登录)
    $airwallex->authentication()->login();
    
    // 获取卡片列表
    $cards = $airwallex->card()->listCards([
        'page_num' => 0,
        'page_size' => 10,
    ]);
    
    // 获取第一张卡片的详情
    if (!empty($cards['items'])) {
        $firstCardId = $cards['items'][0]['id'];
        $cardDetails = $airwallex->card()->getCardDetails($firstCardId);
        $cardLimits = $airwallex->card()->getCardLimits($firstCardId);
    }
    
} catch (AirwallexApiException $e) {
    echo "Error: " . $e->getMessage() . "\n";
    print_r($e->getResponse());
}

use Goletter\Card\CardFactory;

// 推荐
$bundle = CardFactory::slash([
    'base_url' => 'https://api.slash.com',
    'api_key' => 'your-api-key',
    'timeout' => 60,
]);

// 也可直接 new(不经过工厂)
use Goletter\Card\Platforms\Slash\Slash;
$slash = new Slash([
    'base_url' => 'https://api.slash.com',
    'api_key' => 'your-api-key',
    'timeout' => 60,
]);

$adapter = CardFactory::slash($config)->adapter();

$result = $adapter->cardList(['cursor' => '']);
// $result['code'] === 1
// $result['data']['data'] / $result['data']['cursor']

$allCards = [];
$cursor = '';
do {
    $result = $adapter->listCardsPaginated($cursor === '' ? null : $cursor);
    $allCards = array_merge($allCards, $result['data']['data'] ?? []);
    $cursor = (string) ($result['data']['cursor'] ?? '');
} while ($cursor !== '');

$detail = $adapter->cardInfo(['card_id' => 'card-id']);
// $detail['data']['cardNo'] / cvv / cardStatus ...

$api = CardFactory::slash($config)->card();
$raw = $api->listCards(['cursor' => '']);
$card = $api->getCard('card-id', ['

$newCard = $slash->card()->createCard([
    'card_type' => 'virtual',
    'name' => 'Card Name',
    'account_id' => 'account-id',
    // 其他创建所需的数据
    // 具体字段请参考 Slash API 文档
]);

$newCard = $slash->card()->createPhysicalCard([
    'name' => 'Card Name',
    'account_id' => 'account-id',
    // 其他创建所需的数据
]);

$cardId = 'card-id';
$updatedCard = $slash->card()->updateCard($cardId, [
    // 需要更新的字段
]);

$cardId = 'card-id';
$updatedCard = $slash->card()->patchCard($cardId, [
    // 需要更新的字段(部分更新)
]);

$cardId = 'card-id';
$result = $slash->card()->freezeCard($cardId, [
    // 可选:冻结原因等数据
]);

$cardId = 'card-id';
$result = $slash->card()->unfreezeCard($cardId, [
    // 可选:解冻原因等数据
]);

$cardId = 'card-id';
$result = $slash->card()->cancelCard($cardId, [
    // 可选:取消原因等数据
]);

$cardId = 'card-id';
$result = $slash->card()->deleteCard($cardId);

$cardId = 'card-id';
$result = $slash->card()->setSpendingConstraints($cardId, [
    // 消费限制规则
    // 例如:商户类别、交易金额等限制
]);

$cardId = 'card-id';
$constraints = $slash->card()->getSpendingConstraints($cardId);

use Goletter\Card\Platforms\Slash\Exceptions\SlashApiException;
use Goletter\Card\Platforms\Slash\Exceptions\SlashTokenExpiredException;

try {
    $cards = $slash->card()->listCards();
} catch (SlashTokenExpiredException $e) {
    // API Key 无效或过期
    echo "API Key invalid: " . $e->getMessage();
} catch (SlashApiException $e) {
    // 其他 API 错误
    echo "API Error: " . $e->getMessage();
    $response = $e->getResponse(); // 获取错误响应数据
}



use Goletter\Card\Platforms\Slash\Slash;
use Goletter\Card\Platforms\Slash\Exceptions\SlashApiException;

// 初始化
$slash = new Slash([
    'baseUrl' => 'https://api.slash.com',
    'apiKey' => 'your-api-key',
]);

try {
    // 方式一:循环获取所有卡片数据
    $allCards = [];
    $cursor = null;
    
    do {
        $response = $slash->card()->listCardsPaginated($cursor);
        
        // 合并当前页数据
        if (isset($response['data']) && is_array($response['data'])) {
            $allCards = array_merge($allCards, $response['data']);
        }
        
        // 获取下一页游标
        $cursor = $response['metadata']['nextCursor'] ?? null;
    } while ($cursor !== null);
    
    // 方式二:逐页处理(适合大数据量,避免内存占用过大)
    $cursor = null;
    do {
        $response = $slash->card()->listCardsPaginated($cursor);
        
        // 处理当前页的卡片
        foreach ($response['data'] ?? [] as $card) {
            // 处理每张卡片,例如保存到数据库
            // processCard($card);
        }
        
        // 获取下一页游标
        $cursor = $response['metadata']['nextCursor'] ?? null;
    } while ($cursor !== null);
    
    // 获取第一张卡片的详情
    if (!empty($cards['data'])) {
        $firstCardId = $cards['data'][0]['id'];
        $cardDetails = $slash->card()->getCard($firstCardId);
        $constraints = $slash->card()->getSpendingConstraints($firstCardId);
    }
    
    // 创建虚拟卡片
    $newCard = $slash->card()->createCard([
        'card_type' => 'virtual',
        'name' => 'My Virtual Card',
        'account_id' => 'account-id',
    ]);
    
} catch (SlashApiException $e) {
    echo "Error: " . $e->getMessage() . "\n";
    print_r($e->getResponse());
}

use Goletter\Card\Platforms\Lampay\Lampay;

$lampay = new Lampay([
    'base_url' => 'https://api.lampay.app',
    'api_key' => 'your-api-key',
    // 客户端鉴权私钥(签名)
    'private_key' => file_get_contents('/secure/client-auth-private.pem'),
    // 平台鉴权公钥(验签)
    'public_key' => file_get_contents('/secure/platform-auth-public.pem'),
    // 可选:加解密(发卡 / 敏感信息 / Webhook)
    'merchant_enc_private_key' => file_get_contents('/secure/client-enc-private.pem'),
    'platform_enc_public_key' => file_get_contents('/secure/platform-enc-public.pem'),
    'webhook_receiver_key_id' => 'receiver-api-key-biz-id',
    'provider_type' => '10010105',
    'api_version' => '1',
    'timeout' => 60,
]);

// 产品组列表(首次只读联调)
$groups = $lampay->card()->listProductGroups(['page' => 0, 'size' => 20]);

// 卡片列表(分页,page 从 0 开始)
$cards = $lampay->card()->listCards(['page' => 0, 'size' => 20]);

// 卡片详情
$detail = $lampay->card()->getCard('VC_xxx');

// 敏感信息(需配置加密私钥;自动解密)
$reveal = $lampay->card()->revealSensitive('VC_xxx');
// $reveal['sensitive'] => pan / cvv / expiryMonth / expiryYear

// 发卡预检 + 加密发卡(需配置平台加密公钥)
$lampay->card()->createCardPrecheck($payload);
$result = $lampay->card()->createCard($payload, $idempotencyKey);

// 更新消费规则 / 别名
$lampay->card()->updateSpendingControls(['cardInfoBizId' => 'VC_xxx', 'spendingRule' => [...]]);
$lampay->card()->updateRemark('VC_xxx', 'Ops Card');

// 冻结 / 解冻 / 注销
$lampay->card()->freezeCard('VC_xxx');
$lampay->card()->unfreezeCard('VC_xxx');
$lampay->card()->cancelCard('VC_xxx');

// 交易列表
$txs = $lampay->card()->listTransactions(['cardInfoBizId' => 'VC_xxx', 'page' => 0, 'size' => 20]);

$handled = $lampay->webhook()->handle(getallheaders(), file_get_contents('php://input'));
// $handled['event'] / delivery_biz_id / event_type

use Goletter\Card\Platforms\Lampay\Exceptions\LampayApiException;

try {
    $cards = $lampay->card()->listCards(['page' => 0, 'size' => 20]);
} catch (LampayApiException $e) {
    echo $e->getMessage();
    print_r($e->getResponse());
}

use Goletter\Card\Platforms\Photonpay\Photonpay;

$photonpay = new Photonpay([
    'base_url' => 'https://x-api.photonpay.com',
    'api_key' => 'your-api-key',
    'api_secret' => 'your-api-secret',
    'private_key' => 'your-rsa-private-key', // 请求签名
    'token' => 'optional-existing-token',
    'timeout' => 60,
]);

$result = $photonpay->authentication()->login();
// $result['token'] / $result['access_token']

use Goletter\Card\CardFactory;

$bundle = CardFactory::photonpay($config);

// 适配层 → {code, msg, data}
$adapter = $bundle->adapter();
$cards = $adapter->cardList([
    'page_index' => 1,
    'page_size' => 10,
    'from_created_at' => '2024-01-01 00:00:00',
    'to_created_at' => '2024-12-31 23:59:59',
]);
$detail = $adapter->cardInfo(['card_id' => 'card-id']);
$adapter->cardFreeze(['card_id' => 'card-id']);

// SDK 层 → 官方原始 JSON
$api = $bundle->card();
$raw = $api->pagingVccCard(['pageIndex' => 1, 'pageSize' => 10]);
$newCard = $api->openCard([/* 见 Photonpay 文档 */]);

use Goletter\Card\Platforms\Photonpay\Exceptions\PhotonpayApiException;
use Goletter\Card\Platforms\Photonpay\Exceptions\PhotonpayTokenExpiredException;

try {
    $cards = CardFactory::photonpay($config)->adapter()->cardList([
        'page_index' => 1,
        'page_size' => 10,
    ]);
} catch (PhotonpayTokenExpiredException $e) {
    echo "Token expired: " . $e->getMessage();
} catch (PhotonpayApiException $e) {
    echo "API Error: " . $e->getMessage();
    print_r($e->getResponse());
}

use Goletter\Card\CardFactory;

$bundle = CardFactory::wasabi([
    'base_url' => 'https://sandbox-api-merchant.wasabicard.com',
    'api_key' => 'your-api-key',
    'private_key' => file_get_contents('/secure/wasabi-private.pem'),
    'wsb_public_key' => file_get_contents('/secure/wasabi-public.pem'),
    'timeout' => 60,
]);

// 适配层
$cards = $bundle->adapter()->cardList(['page_index' => 1, 'page_size' => 20]);
$detail = $bundle->adapter()->cardInfo(['card_id' => 'xxx']);

// SDK 层
$raw = $bundle->card()->listCards(['pageNum' => 1, 'pageSize' => 20]);
bash
php bin/hyperf.php vendor:publish goletter/hyperf-card