cfxmarkets / php-brokerage-sdk
一个公开的PHP API库,用于访问CFX Markets经纪商API
Requires
- php: >=5.4.0
- cfxmarkets/php-persistence: ^0.3.0 || ^0.4.0 || ^0.5.0 || ^0.6.0
- cfxmarkets/php-public-models: ^1.4.0
- psr/http-message: ~1.0
Requires (Dev)
- guzzlehttp/guzzle: ^6.0.0
- phpunit/phpunit: >=4.8.0
This package is auto-updated.
Last update: 2024-08-25 17:04:15 UTC
README
一个公开的PHP SDK,用于访问CFX Markets经纪商API
这个库帮助通过CFX的经纪商REST API与CFX经纪商进行交互。虽然可以直接使用API,但通过这个SDK使用会更加方便,因为SDK处理了路由和协议一致性的细节,并提供了一种更直观、基于对象的方法来进行访问和输入验证。
在深入之前,有一些关于SDK工作方式的注意事项
- 它抛出异常。你应该假设所有操作都返回预期结果,并且你应该准备好处理抛出的异常。异常在代码级别上有文档说明,所以务必提前阅读,并确保至少在应用级别处理一般异常,以避免向用户输出不愉快的系统输出。以下是一些常见的异常
\\CFX\\Persistence\\ResourceNotFoundException
-- 当尝试get
一个不存在的资源时抛出(例如,$cfx->users->get('non-existent')
)。\\CFX\\BadInputException
-- 当尝试save
一个有用户输入错误的资源时抛出。包括一个getInputErrors
方法,该方法返回原始的jsonapi
格式错误数组。
- SDK被分为三个部分层次:
Context > Datasource > Resource
。Context
(以下示例中的$cfx
)负责促进各种类型资源之间的交互;DataSource
(例如$cfx->users
,$cfx->assets
等)负责管理特定资源的持久化和膨胀(“非持久化”);Resource
(由$cfx->assets->get('ASST001')
,$cfx->users->create()
等返回)负责提供直观且意义明确的接口,用于在系统内使用数据。 - 用户输入错误发生在
Resource
级别,可以使用hasErrors(string $field = null) : bool
,numErrors($field = null) : int
和getErrors($field = null) : array
方法进行探索。相同的这些方法在save
上使用,以生成\\CFX\\BadInputException
,所以你不需要手动检查错误,只需在抛出异常时捕获它即可。
示例
了解SDK使用方法最好的方式是通过示例。以下是如何在CFX系统中执行“立即卖出”功能的逐步示例指南,该功能允许合作伙伴将信息输入到CFX系统中,从而为用户的持仓生成有效、活跃的卖出订单。
实例化Context
要使用CFX SDK,首先需要实例化context。为此,你需要API URL(无论是https://sandbox.apis.cfxtrading.com
还是https://apis.cfxtrading.com
,具体取决于你是否在生产环境中),API密钥和密钥,以及一个可选的Guzzle5.3 HTTP客户端实例(最后一个参数,如果你想要指定特殊选项)
$cfx = new \CFX\SDK\Brokerage\Client( 'https://sandbox.apis.cfxtrading.com', 'my-api-key-12345', 'my-secret-abcde' );
现在可以继续其他流程。
1. 将用户添加到我们的系统中
首先需要确保你的用户在我们的系统中。对于你添加到我们系统中的每个用户,你将获得该用户的CFX用户ID和一个OAuth令牌,它允许你管理用户的账户。你应该将这两个都存储在你的用户表中供以后使用。
假设你还没有在表中添加,你应该继续在我们系统中创建用户
// Try to create the user with information from your database try { // Assume `$myUser` is your user object from your database $user = $cfx->users->create() ->setDisplayName($myUser->getName()) ->setEmail($myUser->getEmail()) ->setPhoneNumber($myUser->getPhone()) ->save(); // Now add the CFX user's id and oauth token to your database $myDb->prepare('UPDATE `users` SET `cfxUserId` = ?, `cfxOAuthToken` = ? WHERE `userId` = ?') ->execute([ $user->getId(), $user->getOAuthTokens()[0]->getId(), $myUser->getId() ]); // If the user already exists in our system, you'll have to stop here and bring the user through our // OAuth flow (not yet implemented) } catch (\CFX\Persistence\DuplicateResourceException $e) { // Redirect to OAuth, then come back when you've got the userId and OAuth token from that }
现在您已经拥有了有效的OAuth令牌,您可以使用它来完成用户的其他流程。
2. 列出或管理资产
在此阶段,您可能想确保用户感兴趣出售的资产已存在于我们的系统中。您可以通过搜索资产,然后创建一个“资产意向”1,如果您没有找到结果
// First, try to get the asset as if it were already in our system try { $assetIntent = null; $asset = $cfx->assets->get('MYASST001'); // If you get an error, then try to create an asset intent } catch (\CFX\Persistence\ResourceNotFoundException $e) { $asset = null; try { $assetIntent = $cfx->assetIntent->create() ->setName('My Asset') ->setDescription("A luxurious condo in Mexico....") ->save(); // If you've already submitted this asset intent, then that intent will be attached to the error and you can use it } catch (\CFX\Persistence\DuplicateResourceException $e) { $assetIntent = $e->getDuplicateResource(); } }
3. 订单意向
现在您已经拥有了有效的CFX用户、资产或资产意向,并且可能已经拥有了启动订单意向所需的所有其他东西,让我们开始吧
// Watch out, could throw exceptions! try { $intent = $cfx->orderIntents->create() ->setType("sell") ->setAsset($asset) ->setAssetIntent($assetIntent) ->setUser($user) ->setOwnerEntity($user->getPersonEntity()) ->setNumShares(12345) ->setPriceHigh(5.25) ->setPriceLow(4.80) ->save(); } catch (\CFX\BadInputException $e) { // Use this to figure out what the user needs to do }
4. 法律信息、银行账户、身份证件、所有权文件和协议文件
订单意向实际上不能转化为实时订单,直到我们收集到用户的一些其他信息。这些包括他们的SSN(或拥有他们出售的资产的法人的税号)、他们的地址、他们的法律名称(如其在声明中显示),一个已验证的银行账户以及一些文件。以下是这些信息在代码中的可能形式
// First, let's add an address for the owner entity try { $personalAddress = $cfx->addresses->create() ->setLabel("Home") ->setStreet1("555 4th St") ->setStreet2("#321") ->setCity("Chicago") ->setState("IL") ->setCountry("USA") ->save(); $user->getPersonEntity() ->setPrimaryAddress($personalAddress); // Now let's add the user's legal name and SSN and their answers to some questions about their FINRA association and corporate ownership $user->getPersonEntity() ->setLegalId('123456789') ->setLegalName($myUser->getLegalName()) ->setFinraStatus(true) ->setFinraStatusText("My wife works for FINRA") ->setCorporateStatus(false) ->save(); // Now add some ID Documents $photoId = $cfx->documents->create() ->setType('id') ->setUrl('https://mydocs.com/my/doc/12345') ->setLegalEntity($user->getPersonEntity()) ->save(); // Now proof of ownership $assetOwnership = $cfx->documents->create() ->setType('ownership') ->setUrl('https://mydocs.com/my/doc/67890') ->setOrderIntent($intent) ->save(); // Now their signed agreement $agreement = $cfx->documents->create() ->setType("agreement") ->setUrl("hellosign:abcde12345") ->setOrderIntent($intent) ->save(); // If you got this far, you may have a valid order by now. Check and see if ($intent->getOrder()) { // Yay!! Now you can show the user information about the order, like its current highest bid, number of bids, etc. } else { // Womp womp, no order yet :(. Will have to wait for a webhook to inform you when the order intent's status changes. } } catch (\CFX\BadInputException $e) { // Do something with this }
注意:当前API版本的文档处理并不理想。在未来版本中,您将首先创建一个文档,然后根据需要将其附加到法律实体或订单意向,这将触发更新该法律实体或意向。但是,目前您必须将订单意向或法律实体附加到文档上,这不会触发订单意向或法律实体的更新。因此,您可能需要手动刷新订单意向以查看它现在是否具有有效的订单。您可以通过调用
$intent = $cfx->orderIntents->get("id=".$intent->getId());
来实现