siberfx/laravel-tryoto
Laravel Tryoto
A Laravel integration for the OTO shipping and fulfillment platform (tryoto.com), built on Laravel's HTTP client. It wraps the OTO REST API v2: orders, delivery rates, shipments, AWB and label printing, tracking, returns, pickup locations, products, stock, coverage and webhooks.
This is an unofficial, community-maintained package. It is not affiliated with OTO.
Contents
- Features
- Requirements
- Installation
- Configuration
- Quick start
- Authentication
- Usage
- Webhooks
- Notifications: Slack, Telegram and email
- Error handling
- Endpoint reference
- Testing your application
- Testing the package
- Changelog
- Contributing
- Security
- Credits
- License
Features
- Around 70 endpoint wrappers covering the main sections of the official OTO API documentation.
- Token handling: the refresh token is exchanged for an access token on first use, the access token is cached, and a
401triggers one refresh and retry. - Sandbox switch: one env flag moves every call to OTO's staging API, with its own token cache.
- Webhooks: register, list, update and delete them from code. The bundled callback route checks the authorization key and signature, then fires a Laravel event.
- Notifications: forward webhook events to Slack, Telegram and/or email, filtered by type or status and optionally queued. Off by default, and needs no extra packages.
- Escape hatch:
call()/request()reach any endpoint with the same authentication. - Tested: a Pest suite checks each wrapper's HTTP method, path, query and body against the docs. CI runs PHP 8.4/8.5 against Laravel 12/13.
Requirements
| Package | PHP | Laravel | Supported |
|---|---|---|---|
| 3.x | 8.4, 8.5 | 12.x, 13.x | Yes |
| 2.x | 8.4, 8.5 | 12.x, 13.x | No |
| 1.x | 8.2, 8.3 | 10.x, 11.x | No |
Installation
composer require siberfx/laravel-tryoto
The service provider is registered automatically through package discovery.
Publish the configuration file:
php artisan vendor:publish --provider="Siberfx\LaravelTryoto\TryotoServiceProvider" --tag=config
Optionally publish the routes file to customise or protect the package routes:
php artisan vendor:publish --provider="Siberfx\LaravelTryoto\TryotoServiceProvider" --tag=routes
Configuration
Add your credentials to .env. The refresh token is generated in the OTO dashboard.
TRYOTO_REFRESH_TOKEN=your-live-refresh-token
TRYOTO_SANDBOX=false
All options in config/laravel-tryoto.php:
| Key | Env variable | Default | Description |
|---|---|---|---|
tryoto.sandbox |
TRYOTO_SANDBOX |
false |
Use the staging API and staging refresh token. |
tryoto.live.url |
TRYOTO_URL |
https://api.tryoto.com |
Live API base URL. |
tryoto.live.token |
TRYOTO_REFRESH_TOKEN |
Live refresh token. | |
tryoto.test.url |
TRYOTO_TEST_URL |
https://staging-api.tryoto.com |
Staging API base URL. |
tryoto.test.token |
TRYOTO_TEST_REFRESH_TOKEN |
Staging refresh token. | |
tryoto.cache_name |
— | oto_api_token |
Cache key for the access token (_sandbox is appended in sandbox mode). |
tryoto.cache_time |
— | 58 |
Minutes to cache the access token (OTO tokens are valid for 60). |
tryoto.timeout |
TRYOTO_TIMEOUT |
30 |
HTTP timeout in seconds. |
tryoto.webhook.url |
TRYOTO_WEBHOOK_URL |
route('tryoto.callback') |
URL registered by setWebhook(). |
tryoto.webhook.type |
TRYOTO_WEBHOOK_TYPE |
orderStatus |
orderStatus, shipmentError, newOrders or walletTransaction. |
tryoto.webhook.authorization_key |
TRYOTO_WEBHOOK_AUTHORIZATION_KEY |
Sent to OTO on registration; required on incoming calls when set. | |
tryoto.webhook.secret_key |
TRYOTO_WEBHOOK_SECRET |
Key OTO uses to sign webhook payloads. | |
tryoto.webhook.verify_signature |
TRYOTO_WEBHOOK_VERIFY_SIGNATURE |
false |
Reject incoming calls whose signature does not match secret_key. |
tryoto.webhook.timestamp_format |
— | yyyy-MM-dd HH:mm:ss |
Timestamp format OTO uses in payloads. |
tryoto.webhook.order_prefix |
— | '' |
Prefix OTO strips from order ids before sending the webhook. |
Notification options (tryoto.notifications.*). Everything defaults to null, so no notification is sent until you set credentials:
| Key | Env variable | Default | Description |
|---|---|---|---|
notifications.locale |
TRYOTO_NOTIFICATIONS_LOCALE |
en |
Message language: en or tr. Other locales fall back to English. |
notifications.types |
— | null |
null for all webhook types, or e.g. ['orderStatus', 'shipmentError']. |
notifications.statuses |
— | null |
null for all order statuses, or e.g. ['delivered', 'returned']. |
notifications.queue |
TRYOTO_NOTIFICATIONS_QUEUE |
null |
Queue name. null sends during the webhook request. |
notifications.queue_connection |
TRYOTO_NOTIFICATIONS_QUEUE_CONNECTION |
null |
Queue connection. null uses the default. |
notifications.slack.webhook_url |
TRYOTO_SLACK_WEBHOOK_URL |
null |
Slack incoming webhook URL. Setting it enables Slack. |
notifications.slack.channel |
TRYOTO_SLACK_CHANNEL |
null |
Channel override (legacy webhooks only). |
notifications.slack.username |
TRYOTO_SLACK_USERNAME |
null |
Bot name override (legacy webhooks only). |
notifications.telegram.bot_token |
TRYOTO_TELEGRAM_BOT_TOKEN |
null |
Bot token from @BotFather. Set it with chat_id to enable Telegram. |
notifications.telegram.chat_id |
TRYOTO_TELEGRAM_CHAT_ID |
null |
User, group or channel id. |
notifications.telegram.thread_id |
TRYOTO_TELEGRAM_THREAD_ID |
null |
Forum topic id (optional). |
notifications.telegram.api_url |
TRYOTO_TELEGRAM_API_URL |
https://api.telegram.org |
For self-hosted Bot API servers. |
notifications.mail.to |
TRYOTO_MAIL_TO |
null |
Recipients, comma separated or an array. Setting it enables email. |
notifications.mail.mailer |
TRYOTO_MAIL_MAILER |
null |
Mailer from config/mail.php. null uses the default. |
notifications.mail.from_address |
TRYOTO_MAIL_FROM_ADDRESS |
null |
Sender address. null uses mail.from.address. |
notifications.mail.from_name |
TRYOTO_MAIL_FROM_NAME |
null |
Sender name. null uses mail.from.name. |
notifications.mail.subject_prefix |
TRYOTO_MAIL_SUBJECT_PREFIX |
[OTO] |
Prepended to the subject, which is the message title. |
Quick start
TryotoService is bound as a singleton. Inject it anywhere:
use Siberfx\LaravelTryoto\app\Services\TryotoService;
class ShippingController
{
public function __construct(private TryotoService $oto)
{
}
public function ship(string $orderId)
{
// pick the first delivery option offered for the order...
$options = $this->oto->getDeliveryFee($orderId);
$optionId = $options['deliveryCompany'][0]['deliveryOptionId'];
// ...create the shipment and return the AWB print URL
$this->oto->createShipment($orderId, $optionId);
return $this->oto->printAwb($orderId)['printAWBURL'];
}
}
Methods return the decoded JSON response as an array. listOrders() and orderDetail() return
objects (stdClass), as in earlier versions.
Authentication
OTO access tokens are valid for one hour. On the first API call the service exchanges your refresh
token (POST /rest/v2/refreshToken) for an access token and caches it for cache_time minutes.
Every request sends it as Authorization: Bearer <token>.
- If OTO answers
401, the token is refreshed and the request is retried once. - If the token exchange itself fails,
Siberfx\LaravelTryoto\app\Exceptions\TryotoExceptionis thrown. $oto->authorize(fresh: true)forces a new token.
Usage
Orders
$oto->createOrder([
'orderId' => '1234',
'pickupLocationCode' => 'jdd_wh',
'createShipment' => false,
'payment_method' => 'paid', // or "cod"
'amount' => 100,
'amount_due' => 0,
'currency' => 'SAR',
'packageCount' => 1,
'packageWeight' => 1,
'orderDate' => '30/12/2026 15:45',
'customer' => [
'name' => 'John Doe',
'email' => 'john@doe.com',
'mobile' => '966500000000',
'address' => 'Street 1',
'city' => 'Riyadh',
'country' => 'SA',
],
'items' => [
['productId' => 1, 'name' => 'Product', 'price' => 100, 'quantity' => 1, 'sku' => 'SKU-1'],
],
]);
$oto->updateOrder($body);
$oto->listOrders(page: 1, filters: ['status' => 'delivered', 'minDate' => '2026-01-01', 'maxDate' => '2026-02-01']);
$oto->orderDetail('1234');
$oto->cancelOrder('1234');
$oto->holdOrder('1234', 'Waiting for stock', 'en');
$oto->unHoldOrder('1234');
$oto->updateOrderStatus(['1234', '1235'], 'delivered', 'Delivered by own fleet', '2026-10-05 12:00:00');
$oto->checkOrderAvailability('1234', ruleIds: [1, 2]);
$oto->customerNotifications('1234');
Shipping prices and shipments
$oto->checkOTODeliveryFee(['weight' => 1, 'originCity' => 'Riyadh', 'destinationCity' => 'Jeddah', 'height' => 10, 'width' => 10, 'length' => 10]);
$oto->checkDeliveryFee(['weight' => 1, 'totalDue' => 0, 'originCity' => 'Riyadh', 'destinationCity' => 'Jeddah']);
$oto->getDeliveryFee('1234'); // options for an existing order
$oto->getDeliveryOptions(['city' => 'Riyadh']); // or ['id' => 10]
$oto->createShipment('1234', deliveryOptionId: 564);
$oto->cancelShipment('1234', shipmentId: 987);
Printing
$oto->printAwb('1234'); // ['printAWBURL' => ..., 'trackingNumber' => ...]
$oto->printAwb('1234', ['printReverseShipment' => true]);
$oto->printAwb('1234', ['internationalProforma' => true]);
$oto->printLabel('1234', type: 'awb', returnUrl: true); // proforma, awb, orderDetailsTemplate, return-order
Tracking
$oto->orderStatus('1234');
$oto->orderStatus('1234', ['labelType' => 'ZPL']);
$oto->orderHistory(['1234', '1235']);
$oto->trackShipment(['trackingNumber' => 'ASD00123', 'deliveryCompanyName' => 'aramex']);
Returns
$oto->createReturnShipment(['orderId' => '1234', 'deliveryOptionId' => 564, 'pickupLocationCode' => 'jdd_wh', 'items' => [/* ... */]]);
$oto->getReturnLink('1234');
$oto->getReturnDetails('1234');
$oto->triggerReturnSms('1234');
Pickup locations
$oto->createPickupLocation(['type' => 'warehouse', 'code' => 'jdd_wh', 'name' => 'Jeddah WH', 'city' => 'Jeddah', 'country' => 'SA' /* ... */]);
$oto->updatePickupLocation(['code' => 'jdd_wh', 'status' => 'active' /* ... */]);
$oto->getPickupLocationList(['status' => 'active']);
$oto->pickupLocationWorkingHours([/* ... */]);
Account and transactions
$oto->healthCheck();
$oto->accountInfo();
$oto->buyCredit(500);
$oto->requestMobileVerification('966500000000');
$oto->verifyMobileNumber('966500000000', $code, $token);
$oto->shippingPriceTransactions(['orderId' => '1234']);
$oto->creditTransactions(['page' => 1, 'perPage' => 50, 'minDate' => '2026-01-01', 'maxDate' => '2026-02-01']);
$oto->shipmentTransactions(['page' => 1]);
$oto->codTransactions(['page' => 1]);
Products, boxes and stock
$oto->createProduct(['productName' => 'T-shirt', 'sku' => 'TS-1', 'price' => 50]);
$oto->productList(currentPage: 1, pageSize: 50);
$oto->addBox('medium', 30, 20, 15); // name, length, width, height (cm)
$oto->updateBox('medium', 30, 25, 15);
$oto->getBox('medium'); // or getBox() for all boxes
$oto->updateStockQuantity(['actionType' => 'adjust', 'locationCode' => 'jdd_wh', 'sku' => 'TS-1', 'qty' => 10]);
$oto->checkInventoryStock(['TS-1', 'TS-2']);
$oto->checkGlobalStock('TS-1');
$oto->createInventoryOrder([/* ... */]);
$oto->updatePackingStatus('1234', 'packed');
$oto->getPackingOrders('jdd_wh');
$oto->availableStoresForPickup($items, selectedCity: 'Riyadh');
$oto->availableCitiesForPickup();
Coverage, cities and addresses
$oto->checkCoverage(['lat' => 24.7, 'lon' => 46.6, 'city' => 'Riyadh']);
$oto->availableCities(limit: 50);
$oto->availableTimeslots(['serviceType' => '...', 'packageSize' => 'small', 'lat' => 24.7, 'lon' => 46.6]);
$oto->getCities('SA', page: 1, perPage: 100);
$oto->getDeliveryEstimation([/* ... */]);
$oto->aiEstimatedDeliveryDates([/* ... */]);
$oto->nationalAddressFromShortCode('RGUC8214');
Any other endpoint
Endpoints without a dedicated method (marketplace, brands, sales channels, OTO Flex, carrier
activation, ...) use the same authentication and retry handling through call() and request():
$oto->call('GET', '/rest/v2/getBrandList'); // array|null
$oto->call('POST', '/rest/v2/assignDriver', ['orderIDs' => ['1234'], 'driverID' => 5]);
$oto->call('GET', '/rest/v2/creditTransactions', query: ['page' => 2]);
$response = $oto->request('GET', '/rest/v2/salesChannel/getSalesChannelsList'); // Illuminate\Http\Client\Response
$response->status();
Webhooks
Registering
$oto->setWebhook(); // defaults from the "webhook" config section
$oto->setWebhook(['webhookType' => 'shipmentError']); // override any field
$oto->listWebhooks(); // or listWebhooks($id)
$oto->updateWebhook(59, ['url' => 'https://example.com/oto']);
$oto->deleteWebhook(59);
OTO allows up to 10 webhooks per account and supports four types: orderStatus, shipmentError,
newOrders and walletTransaction.
[!WARNING] The package exposes
GET /tryoto/set-webhook(routetryoto.set-webhook) for quick setup. It has no middleware, so publish the routes file (--tag=routes) and protect or remove it in production.
Receiving
OTO calls POST|PUT /tryoto/webhook/callback (route tryoto.callback). The controller:
- returns
401ifauthorization_keyis set and theAuthorizationheader doesn't match it (with or without aBearerprefix); - returns
401ifverify_signatureis enabled and the signature is invalid. OTO signsorderId:status:timestampwith HmacSHA256 using yoursecret_key, Base64 encoded; - returns
422for an empty payload; - dispatches
Siberfx\LaravelTryoto\app\Events\TryotoWebhookReceivedand responds{"success": true}.
Handle the event with a listener:
use Illuminate\Support\Facades\Event;
use Siberfx\LaravelTryoto\app\Events\TryotoWebhookReceived;
Event::listen(function (TryotoWebhookReceived $event) {
$orderId = $event->payload['orderId'];
$status = $event->payload['status'] ?? null; // shipmentProcessing, delivered, returned, ...
$tracking = $event->payload['trackingNumber'] ?? null;
Order::where('reference', $orderId)->update(['shipping_status' => $status]);
});
To verify a signature yourself, for example in your own route:
TryotoService::verifyWebhookSignature($request->all(), config('laravel-tryoto.tryoto.webhook.secret_key'));
Notifications: Slack, Telegram and email
Accepted webhook calls can be forwarded to Slack, Telegram and email. Every channel is off until its credentials are
set; leave them null if you don't need notifications.
# Slack: create an incoming webhook at https://api.slack.com/messaging/webhooks
TRYOTO_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T000/B000/XXXX
# Telegram: create a bot with @BotFather and add it to your chat
TRYOTO_TELEGRAM_BOT_TOKEN=123456:ABC-DEF
TRYOTO_TELEGRAM_CHAT_ID=-1001234567890
# Email: uses your app's Laravel mailer (config/mail.php)
TRYOTO_MAIL_TO=ops@shop.test,owner@shop.test
# optional: send from a queue worker instead of during the webhook request
TRYOTO_NOTIFICATIONS_QUEUE=notifications
# optional: message language, en (default) or tr
TRYOTO_NOTIFICATIONS_LOCALE=tr
Each webhook type gets its own message:
| Webhook type | Example message |
|---|---|
orderStatus |
✅ Order 1234 is delivered · Carrier: aramex · Tracking number · tracking link |
shipmentError |
⚠️ Shipment error for order 7523 · Error · Code · Carrier response |
newOrders |
🆕 New order OID-23331-1035 · Status · Total · Payment · Customer · Items |
walletTransaction |
💳 Wallet transaction -29 · Order · Type · Status · Remaining balance |
Limit what gets sent in config/laravel-tryoto.php:
'notifications' => [
'types' => ['orderStatus', 'shipmentError'], // null = all types
'statuses' => ['delivered', 'returned'], // null = all statuses (orderStatus only)
// ...
],
Emails are HTML, with the same title, fields and tracking button as the chat messages. The subject is
the message title, e.g. [OTO] ✅ Order 1234 is delivered.
A failing channel is passed to Laravel's exception handler with report(). It doesn't stop the
other channels and doesn't change the response sent to OTO.
Languages
Messages are in English by default. Set TRYOTO_NOTIFICATIONS_LOCALE=tr to send them in Turkish:
| Locale | Example title | Field labels |
|---|---|---|
en |
✅ Order 1234 is delivered | Status, Carrier, Tracking number |
tr |
✅ 1234 numaralı sipariş: teslim edildi | Durum, Kargo firması, Takip numarası |
The language is set by this setting only, not by the app's app.locale, so notifications stay
the same language no matter which user triggered them. Known OTO status codes (delivered,
outForDelivery, pickedUp, ...) get readable names in the title. Unknown codes are shown as
sent, and the Status field always shows the raw code.
To change the wording or add another language, publish the language files:
php artisan vendor:publish --provider="Siberfx\LaravelTryoto\TryotoServiceProvider" --tag=lang
This copies them to lang/vendor/tryoto/{en,tr}/notifications.php. Add e.g.
lang/vendor/tryoto/de/notifications.php and set the locale to de. Any line missing from a
translation falls back to English.
You can also pick the language per message:
TryotoMessage::fromWebhook($payload, 'tr');
TryotoMessage::make('Günlük rapor', 'tr')->field('Kargolanan', 42);
Sending your own messages
use Siberfx\LaravelTryoto\app\Notifications\TryotoMessage;
use Siberfx\LaravelTryoto\app\Notifications\TryotoNotifier;
app(TryotoNotifier::class)->send(
TryotoMessage::make('📦 Daily shipping report')
->field('Shipped', 42)
->field('Delivered', 37)
->link('https://app.tryoto.com', 'Open OTO')
);
Custom channels
Implement NotificationChannel and register it, for example in AppServiceProvider::boot():
use Siberfx\LaravelTryoto\app\Notifications\Channels\NotificationChannel;
use Siberfx\LaravelTryoto\app\Notifications\TryotoMessage;
use Siberfx\LaravelTryoto\app\Notifications\TryotoNotifier;
class DiscordChannel implements NotificationChannel
{
public function isConfigured(): bool
{
return filled(config('services.discord.webhook'));
}
public function send(TryotoMessage $message): void
{
Http::post(config('services.discord.webhook'), ['content' => $message->title])->throw();
}
}
app(TryotoNotifier::class)->extend('discord', new DiscordChannel());
Error handling
Non-2xx responses aren't thrown as exceptions. OTO's error body is returned so you can inspect it:
$result = $oto->cancelOrder('missing');
// ['success' => false, 'otoErrorCode' => 'OTO1002', 'otoErrorMessage' => 'The order ID does not exist']
if (($result['success'] ?? false) !== true) {
report(new RuntimeException($result['otoErrorMessage'] ?? 'OTO request failed'));
}
Use request() when you need the HTTP status code. Only a failed token exchange throws:
use Siberfx\LaravelTryoto\app\Exceptions\TryotoException;
try {
$oto->accountInfo();
} catch (TryotoException $e) {
$e->getMessage(); // "OTO authorization failed: Refresh Token is required (HTTP 400)"
$e->response; // the Illuminate\Http\Client\Response from /refreshToken
}
The full list of OTO1xxx error codes is in the "Error Codes" section of the API docs.
Endpoint reference
| Section | Endpoint | Method |
|---|---|---|
| Authorization | POST /rest/v2/refreshToken |
authorize() |
GET /rest/v2/healthCheck |
healthCheck() |
|
| Account | GET /rest/v2/accountInfo |
accountInfo() |
POST /rest/v2/buyCredit |
buyCredit() |
|
POST /rest/v2/requestMobileVerification |
requestMobileVerification() |
|
POST /rest/v2/verifyMobileNumber |
verifyMobileNumber() |
|
| Transactions | POST /rest/v2/getShippingPriceTransactionsList |
shippingPriceTransactions() |
GET /rest/v2/creditTransactions |
creditTransactions() |
|
GET /rest/v2/shipmentTransactions |
shipmentTransactions() |
|
GET /rest/v2/codTransactions |
codTransactions() |
|
| Orders | POST /rest/v2/createOrder |
createOrder() |
POST /rest/v2/updateOrder |
updateOrder() |
|
POST /rest/v2/updateOrderStatus |
updateOrderStatus() |
|
POST /rest/v2/cancelOrder |
cancelOrder() |
|
GET /rest/v2/orders |
listOrders() |
|
POST /rest/v2/holdOrder |
holdOrder() |
|
POST /rest/v2/unHoldOrder |
unHoldOrder() |
|
GET /rest/v2/orderDetails |
orderDetail() |
|
POST /rest/v2/checkOrderAvailability |
checkOrderAvailability() |
|
GET /rest/v2/orders/{orderId}/customer-notifications |
customerNotifications() |
|
| Shipping prices | POST /rest/v2/checkOTODeliveryFee |
checkOTODeliveryFee() |
POST /rest/v2/checkDeliveryFee |
checkDeliveryFee() |
|
POST /rest/v2/getDeliveryFee |
getDeliveryFee() |
|
GET /rest/v2/getDeliveryOptions |
getDeliveryOptions() |
|
| Shipments | POST /rest/v2/createShipment |
createShipment() |
POST /rest/v2/cancelShipment |
cancelShipment() |
|
GET /rest/v2/print/{orderId} |
printAwb() |
|
POST /rest/v2/printLabel |
printLabel() |
|
| Tracking | POST /rest/v2/orderStatus |
orderStatus() |
POST /rest/v2/orderHistory |
orderHistory() |
|
POST /rest/v2/trackShipment |
trackShipment() |
|
| Return shipments | POST /rest/v2/createReturnShipment |
createReturnShipment() |
POST /rest/v2/getReturnLink |
getReturnLink() |
|
POST /rest/v2/getReturnDetails |
getReturnDetails() |
|
POST /rest/v2/triggerReturnSms |
triggerReturnSms() |
|
| Pickup locations | POST /rest/v2/createPickupLocation |
createPickupLocation() |
POST /rest/v2/updatePickupLocation |
updatePickupLocation() |
|
GET /rest/v2/getPickupLocationList |
getPickupLocationList() |
|
POST /rest/v2/pickupLocationWorkingHours |
pickupLocationWorkingHours() |
|
| Webhooks | POST /rest/v2/webhook |
setWebhook() |
GET /rest/v2/webhook |
listWebhooks() |
|
PUT /rest/v2/webhook |
updateWebhook() |
|
DELETE /rest/v2/webhook |
deleteWebhook() |
|
| Products | POST /rest/v2/createProduct |
createProduct() |
POST /rest/v2/productList |
productList() |
|
POST /rest/v2/addBox |
addBox() |
|
POST /rest/v2/updateBox |
updateBox() |
|
GET /rest/v2/getBox |
getBox() |
|
| Stock management | POST /rest/v2/updateStockQuantity |
updateStockQuantity() |
GET /rest/v2/checkInventoryStock |
checkInventoryStock() |
|
GET /rest/v2/checkGlobalStock |
checkGlobalStock() |
|
POST /rest/v2/createInventoryOrder |
createInventoryOrder() |
|
POST /rest/v2/updatePackingStatus |
updatePackingStatus() |
|
POST /rest/v2/getPackingOrders |
getPackingOrders() |
|
POST /rest/v2/availableStoresForPickup |
availableStoresForPickup() |
|
POST /rest/v2/availableCitiesForPickup |
availableCitiesForPickup() |
|
| Carrier & coverage | POST /rest/v2/checkCoverage |
checkCoverage() |
POST /rest/v2/availableCities |
availableCities() |
|
POST /rest/v2/availableTimeslots |
availableTimeslots() |
|
POST /rest/v2/getCities |
getCities() |
|
POST /rest/v2/getDeliveryEstimation |
getDeliveryEstimation() |
|
POST /rest/v2/aiEstimatedDeliveryDates |
aiEstimatedDeliveryDates() |
|
| National address | POST /rest/v2/getNationalAddressFromShortCode |
nationalAddressFromShortCode() |
| Anything else | any | call() / request() |
Testing your application
The package uses Laravel's HTTP client, so Http::fake() keeps your tests away from the real API:
use Illuminate\Support\Facades\Http;
use Siberfx\LaravelTryoto\app\Services\TryotoService;
it('ships an order', function () {
Http::fake([
'*/rest/v2/refreshToken' => Http::response(['access_token' => 'fake-token']),
'*/rest/v2/createShipment' => Http::response(['success' => true, 'shipmentId' => 1]),
]);
app(TryotoService::class)->createShipment('1234', 564);
Http::assertSent(fn ($request) => str_ends_with($request->url(), '/rest/v2/createShipment')
&& $request['orderId'] === '1234');
});
Testing the package
composer install
composer test # vendor/bin/pest
composer test-coverage # requires Xdebug or PCOV
Changelog
See CHANGELOG.md for what changed in each release.
Contributing
Pull requests are welcome. See CONTRIBUTING.md.
Security
If you find a security issue, email info@siberfx.com instead of opening an issue. See SECURITY.md.
Credits
- Selim Görmüş - Lead Software Engineer & Maintainer
- All contributors
License
The MIT License (MIT). See LICENSE.md for details.
Related Packages
Powerful PHP database abstraction layer (DBAL) with many features for database s...
Laravel Serializable Closure provides an easy and secure way to serialize closur...
Cli error handling for console/command-line PHP applications.
Version History
| Version | Released | PHP | Laravel | License |
|---|---|---|---|---|
| 2.0.0 | ^8.4 | ^12.0| | MIT | |
| 1.0.1 | ^8.2| | ^10.40| | MIT | |
| 1.0.0 | ^8.2| | ^10.40| | MIT |