Skip to content

Conventions & Best Practices

To ensure consistency and maintainability across all Gateway integrations, please adhere to the following conventions.

  • Format: Lowercase, no spaces or special characters (except underscores if absolutely necessary).
  • Usage: Used in database (services table), seeders, and URL paths.
  • Examples: shopify, shopifyv2, woocommerce, amazon_sp.
  • Format: PascalCase of Service Type + Integration.
  • Location: app/Classes/.
  • Examples:
    • shopify -> ShopifyIntegration
    • shopifyv2 -> Shopifyv2Integration (Note: v is lowercase if part of type, or CamelCase depending on preference, but be consistent)
    • amazon_sp -> AmazonSpIntegration
  • Format: snake_case.
  • Standard Resources:
    • get_orders (Import)
    • get_products (Import)
    • sync_inventory (Export)
    • update_tracking (Export)
    • acknowledge_orders (Utility)

Integrations run in background jobs. If they crash, the job fails. Capture exceptions and return formatted error responses when possible, or let the exception bubble up if it’s a transient network error (to trigger retry).

// Good: Catch expected API errors
if ($response->failed()) {
return [
'success' => false,
'message' => "API Error: " . $response->body()
];
}
// Good: Let network timeouts bubble up to retry job
// Http::retry(3, 100)->get(...)

Use the Log facade with context.

Log::error("Integration {$this->integration->id} failed to sync inventory", [
'error' => $e->getMessage(),
'sku' => $sku
]);

Parameters like client_secret or API keys must be stored in the integration configuration (database) or environment variables (config/services.php).

In ServicesSeeder, parameters that handle secrets should use type => 'password' so they are masked in the UI.

[
'name' => 'api_secret',
'type' => 'password', // ✅ Rendered as *****
'required' => true
]

Always implement pagination when fetching data. Do not attempt to fetch all orders in a single request.

do {
$response = $client->get('orders', ['page' => $page]);
// process...
$page++;
} while ($response->hasMorePages());

Respect the platform’s API rate limits. Sleep if necessary, or better yet, use Laravel’s job middleware for rate limiting.

Ensure mapped fields match the expected types in Order class.

  • quantity should be integer
  • price should be float
  • date should be a valid date string (ISO 8601 preferred)

Provide sensitive defaults if optional data is missing.

  • Default status to ‘processing’ if mapping is unclear.
  • Default country to ‘US’ if missing (but log warning).

Ensure ref_number (External ID) is consistently mapped. The Gateway uses this to prevent duplicate order imports. If you change how you generate ref_number, you risk duplicating orders.