Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 59 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ A complete PHP SDK for interacting with the Hostinger API, allowing you to progr
* [Reset Hostname](#reset-hostname)
* [Get Virtual Machine](#get-virtual-machine)
* [Get Virtual Machine List](#get-virtual-machine-list)
* [Purchase New Virtual Machine](#purchase-new-virtual-machine)
* [Get Metrics](#get-metrics)
* [Set Nameservers](#set-nameservers)
* [Set Panel Password](#set-panel-password)
Expand Down Expand Up @@ -378,7 +379,7 @@ foreach ($domains as $domain) {

#### Purchase New Domain

Purchases and registers a new domain name. Returns an Order DTO.
Purchases and registers a new domain name.

*Doc:* [API Reference](https://developers.hostinger.com/#tag/domains-portfolio/POST/api/domains/v1/portfolio)

Expand Down Expand Up @@ -2031,6 +2032,63 @@ foreach ($vms as $vm) {
}
```

#### Purchase New Virtual Machine

Allows you to buy (purchase) and setup a new virtual machine.

If virtual machine setup fails for any reason, login to hPanel and complete the setup manually.

If no payment method is provided, your default payment method will be used automatically.

*Doc:* [API Reference](https://developers.hostinger.com/#tag/vps-virtual-machine/POST/api/vps/v1/virtual-machines)

```php
$data = [
'item_id' => 'hostingercom-vps-kvm2-usd-1m',
'payment_method_id' => 1327362,
'setup' => [
'template_id' => 1130,
'data_center_id' => 19,
'post_install_script_id' => 6324,
'password' => 'MyS3cureP@ssw0rd!',
'hostname' => 'my.server.tld',
'install_monarx' => false,
'enable_backups' => true,
'ns1' => '1.1.1.1',
'ns2' => '1.0.0.1',
'public_key' => [
'name' => 'my-key',
'key' => 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC2X...'
]
],
'coupons' => ['VPSPROMO'],
];

$order = $hostinger->vps()->virtualMachines()->purchase($data);

$order->id; // 2957087
$order->subscription_id; // Azz353Uhl1xC54pR0
$order->status->value; // completed
$order->currency; // USD
$order->subtotal; // 899
$order->total; // 1080

$order->billing_address->first_name; // John
$order->billing_address->last_name; // Doe
$order->billing_address->company; // null
$order->billing_address->address_1; // null
$order->billing_address->address_2; // null
$order->billing_address->city; // null
$order->billing_address->state; // null
$order->billing_address->zip; // null
$order->billing_address->country; // NL
$order->billing_address->phone; // null
$order->billing_address->email; // john@doe.tld

$order->created_at->format('Y-m-d H:i:s'); // 2025-02-27 11:54:22
$order->updated_at->format('Y-m-d H:i:s'); // 2025-02-27 11:54:22
```

#### Get Metrics

Retrieves historical performance metrics (CPU, RAM, Disk, Network, Uptime) for a VM within a specified time range.
Expand Down
49 changes: 48 additions & 1 deletion src/Resources/Vps/VirtualMachine.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace DerrickOb\HostingerApi\Resources\Vps;

use DerrickOb\HostingerApi\Data\Billing\Order;
use DerrickOb\HostingerApi\Data\PaginatedResponse;
use DerrickOb\HostingerApi\Data\Vps\Action;
use DerrickOb\HostingerApi\Data\Vps\Metrics;
Expand Down Expand Up @@ -43,6 +44,52 @@ public function list(): array
return $this->transform(VirtualMachineData::class, $response);
}

/**
* Purchase new virtual machine.
*
* Allows you to buy (purchase) and setup a new virtual machine.
* If virtual machine setup fails for any reason, login to hPanel and complete the setup manually.
* If no payment method is provided, your default payment method will be used automatically.
*
* @param array{
* item_id: string,
* payment_method_id?: int,
* setup: array{
* template_id: int,
* data_center_id: int,
* password?: string,
* hostname?: string,
* install_monarx?: bool,
* enable_backups?: bool,
* ns1?: string,
* ns2?: string,
* post_install_script_id?: int,
* public_key?: array{
* name: string,
* key: string
* }
* },
* coupons?: array<int, string>
* } $data Purchase and setup data for the virtual machine
*
* @return Order The resulting order details
*
* @throws AuthenticationException When authentication fails (401)
* @throws ValidationException When validation fails (422)
* @throws RateLimitException When rate limit is exceeded (429)
* @throws ApiException For other API errors
*
* @link https://developers.hostinger.com/#tag/vps-virtual-machine/POST/api/vps/v1/virtual-machines
*/
public function purchase(array $data): Order
{
$version = $this->getApiVersion();
$response = $this->client->post(sprintf('/api/vps/%s/virtual-machines', $version), $data);

/** @var Order */
return $this->transform(Order::class, $response);
}

/**
* Get virtual machine details.
*
Expand Down Expand Up @@ -84,7 +131,7 @@ public function get(int $virtualMachineId): VirtualMachineData
* name: string,
* key: string
* }
* } $data Setup data for the virtual machine
* } $data Setup data for the virtual machine.
*
* @return VirtualMachineData The setup virtual machine
*
Expand Down
36 changes: 36 additions & 0 deletions tests/Unit/Resources/Vps/VirtualMachineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace DerrickOb\HostingerApi\Tests\Unit\Resources\Vps;

use DerrickOb\HostingerApi\Data\Billing\Order;
use DerrickOb\HostingerApi\Data\PaginatedResponse;
use DerrickOb\HostingerApi\Data\Vps\Action;
use DerrickOb\HostingerApi\Data\Vps\Action as ActionData;
Expand Down Expand Up @@ -418,3 +419,38 @@
expect($response)->toBeInstanceOf(Action::class)
->and($response->id)->toBe($action['id']);
});

test('can purchase new virtual machine', function (): void {
$faker = faker();
$itemId = 'hostingercom-vps-kvm2-usd-1m';
$paymentMethodId = $faker->randomNumber(6);

$setupData = [
'template_id' => $faker->randomNumber(7),
'data_center_id' => $faker->randomNumber(2),
'password' => $faker->password(12),
'hostname' => $faker->domainName(),
];

$purchaseData = [
'item_id' => $itemId,
'payment_method_id' => $paymentMethodId,
'setup' => $setupData,
'coupons' => ['VPSPROMO'],
];

$orderResponse = TestFactory::order();

$client = createMockClient();
$client->shouldReceive('post')
->with('/api/vps/v1/virtual-machines', $purchaseData)
->once()
->andReturn($orderResponse);

$resource = new VirtualMachine($client);
$response = $resource->purchase($purchaseData);

expect($response)->toBeInstanceOf(Order::class)
->and($response->id)->toBe($orderResponse['id'])
->and($response->status->value)->toBe($orderResponse['status']);
});