{"id":20887931,"url":"https://github.com/nickdnk/gatewayapi-php","last_synced_at":"2025-08-19T06:38:13.030Z","repository":{"id":53252937,"uuid":"173374103","full_name":"nickdnk/gatewayapi-php","owner":"nickdnk","description":"PHP library for integration with GatewayAPI.","archived":false,"fork":false,"pushed_at":"2025-08-12T18:02:03.000Z","size":153,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-12T20:16:13.543Z","etag":null,"topics":["gatewayapi","library","php","php-library","php7","php8","sms","sms-api","sms-gateway"],"latest_commit_sha":null,"homepage":"https://gatewayapi.com","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nickdnk.png","metadata":{"files":{"readme":"readme.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-03-01T22:04:17.000Z","updated_at":"2025-08-12T18:02:06.000Z","dependencies_parsed_at":"2025-08-12T20:11:16.554Z","dependency_job_id":"9abcd6a0-ed8a-4d98-80b9-88445b131524","html_url":"https://github.com/nickdnk/gatewayapi-php","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/nickdnk/gatewayapi-php","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickdnk%2Fgatewayapi-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickdnk%2Fgatewayapi-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickdnk%2Fgatewayapi-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickdnk%2Fgatewayapi-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nickdnk","download_url":"https://codeload.github.com/nickdnk/gatewayapi-php/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickdnk%2Fgatewayapi-php/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271113809,"owners_count":24701614,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-19T02:00:09.176Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gatewayapi","library","php","php-library","php7","php8","sms","sms-api","sms-gateway"],"created_at":"2024-11-18T08:23:23.092Z","updated_at":"2025-08-19T06:38:12.999Z","avatar_url":"https://github.com/nickdnk.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://github.com/nickdnk/gatewayapi-php/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/nickdnk/gatewayapi-php/actions)\n[![Coverage Status](https://coveralls.io/repos/github/nickdnk/gatewayapi-php/badge.svg?branch=master)](https://coveralls.io/github/nickdnk/gatewayapi-php?branch=master)\n# GatewayAPI PHP Library\n\nThis library will allow you to integrate the **GatewayAPI.com** API in your project using modern PHP.\nFor full description of their API, error codes and so on, see: \u003chttps://gatewayapi.com/docs\u003e.\n\n### Prerequisites\n\nYou need an active account at \u003chttps://www.gatewayapi.com\u003e to use this library.\nOnce you have that you need to generate an API key/secret pair under **API** -\u003e **API Keys**.\n\n\n### Installation\n\nTo include this in your project, install it using Composer.\n\nThis library requires PHP \u003e= 7.3 and is tested against 8.0, 8.1, 8.2, 8.3 and 8.4.\n\n`composer require nickdnk/gatewayapi-php`\n\n### How to use\n\n#### Example #1: Sending SMS\n\n```php\nuse nickdnk\\GatewayAPI\\GatewayAPIHandler;\nuse nickdnk\\GatewayAPI\\Entities\\Request\\Recipient;\nuse nickdnk\\GatewayAPI\\Entities\\Request\\SMSMessage;\n\n// Pass `true` as the third parameter to use GatewayAPI in EU-only mode.\n// This requires an EU account. See https://gatewayapi.com/blog/new-eu-setup-for-gatewayapi-customers/.\n$handler = new GatewayAPIHandler('my_key', 'my_secret', false);\n\n$message1 = new SMSMessage(\n    \n    // The message you want to send. Include any placeholder tag strings.\n    'Hello, %FIRSTNAME%! Your code is: %CODE%.',\n    \n    // The name of the sender as seen by the recipient.\n    // 1-11 ASCII characters, spaces are removed. \n    'MyService',\n\n    // An array containing the recipient(s) you want to send the message\n    // to. You can also pass an empty array and add recipients later on.\n    // See the example below the constructor.\n    [new Recipient(4512345678, ['John', '23523'])],\n\n    // Arbitrary label added to your message(s).\n    // Pass null if you don't need this.\n    'customer1',\n\n    // The strings to replace in your message with tag values for each\n    // recipient. Pass an empty array if you don't use tags in your message.\n    ['%FIRSTNAME%', '%CODE%'],\n    \n    // The UNIX timestamp for when you want your message to be sent.\n    // Pass null to send immediately. This should *not* be less than\n    // the current UNIX time. This example sends in 1 hour.\n    time() + 3600,\n    \n    // The message class to use. Note that prices vary. The secret class\n    // requires approval by GatewayAPI on your account before you can use\n    // it, otherwise you will get an error.\n    SMSMessage::CLASS_STANDARD,\n    \n    // The encoding to use. UCS2 allows emojis but increases cost. Default\n    // or null is UTF8, which uses the GSM-7 character set.\n    SMSMessage::ENCODING_UTF8\n\n);\n\n// If you prefer a shorter constructor, you can use the default values\n// and set your parameters after construction.\n$message2 = new SMSMessage('Hello %NAME%! Your code is: %CODE%', 'MyService');\n\n$message2-\u003esetSendTime(time() + 3600);\n$message2-\u003esetClass(SMSMessage::CLASS_PREMIUM);\n$message2-\u003esetUserReference('customer1');\n$message2-\u003esetTags(['%NAME%', '%CODE%']);\n$message2-\u003esetCallbackUrl('https://example.com/callback');\n$message2-\u003esetEncoding(SMSMessage::ENCODING_UTF8);\n\n$message2-\u003eaddRecipient(new Recipient(4587652222, ['Martha', '42442']));\n\ntry {\n\n    // Note that a single SMSMessage must not contain more than 10,000\n    // recipients. If you want to send to more than 10,000 you should split\n    // your recipients into several SMSMessages. You can, however, send\n    // multiple SMSMessages in a single request.\n    $result = $handler-\u003edeliverMessages(\n        [\n            $message1,\n            $message2\n        ]\n    );\n    \n    // All message IDs returned.\n    $result-\u003egetMessageIds();\n\n    // The total cost of this request (all message IDs combined).\n    $result-\u003egetTotalCost();\n\n    // Currency you were charged in.\n    $result-\u003egetCurrency();\n\n    // The number of messages sent. For a message that's 3 SMSes long\n    // with 1000 recipients, this will be 3000.\n    $totalMessagesSent = $result-\u003egetTotalSMSCount();\n\n    // Messages sent to UK only.\n    $ukMessages = isset($result-\u003egetCountries()['UK'])\n    ? $result-\u003egetCountries()['UK']\n    : 0;\n\n} catch (\\nickdnk\\GatewayAPI\\Exceptions\\InsufficientFundsException $e) {\n\n    /**\n     * Extends GatewayRequestException.\n     * \n     * Your account has insufficient funds and you cannot send the\n     * message(s) before you buy more credits at gatewayapi.com.\n     * \n     * The request body can be retried after you top up your balance.\n     */\n\n} catch (\\nickdnk\\GatewayAPI\\Exceptions\\MessageException $e) {\n\n    /**\n     * Extends GatewayRequestException.\n     * \n     * This should not happen if you properly use the library and pass\n     * correct data into the functions, but it indicates that whatever\n     * you're doing is not allowed by GatewayAPI.\n     * \n     * It can happen if you add the same phone number (recipient) twice \n     * to an SMSMessage or if you don't use the tags function correctly,\n     * such as not providing a tag value for a recipient within a message\n     * that has a defined set of tags, or if you provide a tag value as\n     * an integer.\n     * \n     * To add the same phone number twice to one request it must be in\n     * different SMSMessage objects.\n     * \n     * Requests that throw this exception should *not* be retried!\n     */\n\n    // The error code (may be null)\n    $e-\u003egetGatewayAPIErrorCode();\n    \n    // Error message, if present.\n    $e-\u003egetMessage();\n\n    // Full response.\n    $e-\u003egetResponse()-\u003egetBody();\n\n} catch (\\nickdnk\\GatewayAPI\\Exceptions\\SuccessfulResponseParsingException $e) {\n\n    /**\n     * Extends GatewayRequestException.\n     * \n     * If you implement automatic retries of failed requests, you should\n     * check for this exception. It is unlikely to ever occur, but it\n     * could happen if GatewayAPI changed their API or there was an error\n     * in the library. This could potentially trigger retries for requests\n     * that succeeded which would be expensive as well as problematic\n     * for recipients.\n     */\n    \n    // Error message.\n    $e-\u003egetMessage();\n\n    // Full response.\n    $e-\u003egetResponse()-\u003egetBody();\n\n} catch (\\nickdnk\\GatewayAPI\\Exceptions\\UnauthorizedException $e) {\n\n    /**\n     * Extends GatewayRequestException.\n     * \n     * Something is wrong with your credentials or your IP is\n     * banned. Make sure you API key and secret are valid or contact\n     * customer support.\n     *\n     * The request body can be retried if you provide different\n     * credentials (or fix whatever is wrong).\n     */\n\n    // The error code (may be null)\n    $e-\u003egetGatewayAPIErrorCode();\n    \n    // Error message, if present.\n    $e-\u003egetMessage();\n        \n    // Full response.\n    $e-\u003egetResponse()-\u003egetBody();\n\n} catch (\\nickdnk\\GatewayAPI\\Exceptions\\GatewayServerException $e) {\n    \n    /**\n     * Extends GatewayRequestException.\n     * \n     * Something is wrong with GatewayAPI.com. This exception simply\n     * extends GatewayRequestException but only applies to 500-range\n     * errors.\n     *\n     * The request body can (most likely) be retried.\n     */\n    \n     // The error code (may be null)\n    $e-\u003egetGatewayAPIErrorCode();\n    \n    // Error message.\n    $e-\u003egetMessage();\n        \n    // Full response.\n    $e-\u003egetResponse()-\u003egetBody();\n    \n} catch (\\nickdnk\\GatewayAPI\\Exceptions\\ConnectionException $e) {\n\n    /**\n     * Connection to GatewayAPI failed or timed out. Try again or\n     * check their server status at https://status.gatewayapi.com/\n     *\n     * The request can/should be retried. This library does not \n     * automatically retry requests that fail for this reason. \n     */\n    \n    // Error message.\n    $e-\u003egetMessage();\n\n} catch (\\nickdnk\\GatewayAPI\\Exceptions\\BaseException $e) {\n\n    /**\n     * Something else is wrong.\n     * All exceptions inherit from this one, so you can catch this error\n     * to handle all errors the same way or implement your own error\n     * handler based on the error code. Remember to check for nulls.\n     * \n     * This exception is abstract, so you can check which class it is\n     * and go from there.\n     */\n    \n    // Error message.\n    $e-\u003egetMessage();\n\n    if ($e instanceof \\nickdnk\\GatewayAPI\\Exceptions\\GatewayServerException) {\n        \n        // The error code (may be null).\n        $e-\u003egetGatewayAPIErrorCode();\n\n        $response = $e-\u003egetResponse();\n\n        $response-\u003egetBody();\n        $response-\u003egetStatusCode();\n\n    }\n\n}\n```\n#### Example #2: Canceling scheduled messages\nYou can cancel a scheduled SMS based on the ID returned when sending.\nAs this method creates a pool of requests (1 per message ID) it does\nnot throw exceptions but returns an array of `CancelResult`. Each of\nthese contain the status and (if failed) exception of the request.\n```php\nuse nickdnk\\GatewayAPI\\Entities\\CancelResult;\nuse nickdnk\\GatewayAPI\\GatewayAPIHandler;\n\n$handler = new GatewayAPIHandler('my_key', 'my_secret');\n$results = $handler-\u003ecancelScheduledMessages([1757284, 1757288]);\n\nforeach ($results as $cancelResult) {\n    \n    // The ID of the canceled message is always available.\n    $cancelResult-\u003egetMessageId();\n    \n    if ($cancelResult-\u003egetStatus() === CancelResult::STATUS_SUCCEEDED) {\n        \n        // Success. Obviously.\n        \n    } elseif ($cancelResult-\u003egetStatus() === CancelResult::STATUS_FAILED) {\n\n        // Get the exception of a failed request.\n        $cancelResult-\u003egetException();\n        \n    }\n\n}\n```\n#### Example #3: Parsing webhooks\nYou can easily parse webhooks sent from GatewayAPI to your server\nusing the `Webhook` class. This uses the JWT header to ensure that\nthe webhook has not been tampered with and is in fact coming from\na trusted source.\n\nTo set up webhooks go to  **API** -\u003e **Web Hooks** -\u003e **REST**. Specify\na JWT secret under Authentication after you've created the webhook.\n\nTwo types of webhooks can be sent; delivery status notifications and\nincoming messages (MO traffic). Both are parsed by `Webhook` and\nreturned as their corresponding class. To read incoming messages you have to\nsubscribe to a keyword or number under **Subscriptions** -\u003e **Keywords / Numbers**\nand assign the keyword or number to a webhook.\n```php\nuse nickdnk\\GatewayAPI\\Entities\\Webhooks\\DeliveryStatusWebhook;\nuse nickdnk\\GatewayAPI\\Entities\\Webhooks\\IncomingMessageWebhook;\nuse nickdnk\\GatewayAPI\\Entities\\Webhooks\\Webhook;\nuse Psr\\Http\\Message\\RequestInterface;\nuse Psr\\Http\\Message\\ResponseInterface;\n\n/**\n * The webhook parser is based on PSR-7 allowing you to pass a $request\n * object directly into the class and get a webhook back.\n */\nfunction (RequestInterface $request, ResponseInterface $response) {\n    \n    try {\n\n        $webhook = Webhook::constructFromRequest($request, 'my_jwt_secret');\n        \n        // Determine the type of webhook if you don't already know.\n        if ($webhook instanceof DeliveryStatusWebhook) {\n            \n            $webhook-\u003egetPhoneNumber();\n            $webhook-\u003egetStatus();\n            \n        } elseif ($webhook instanceof IncomingMessageWebhook) {\n            \n            $webhook-\u003egetPhoneNumber();\n            $webhook-\u003egetWebhookLabel();\n            $webhook-\u003egetMessageText();\n            \n        }\n    \n    } catch (\\nickdnk\\GatewayAPI\\Exceptions\\WebhookException $exception) {\n        \n        // Something is wrong with the webhook or it was not correctly\n        // signed. Take a look at your configuration.\n        $exception-\u003egetMessage();\n        \n    }\n    \n}\n\n/**\n * Or if you don't have a PSR-7 request handy, you can pass the JWT\n * directly into this method instead. Note that the JWT contains\n * the entire payload, which is duplicated unsigned in the body of the\n * request. We don't read the request body at all.\n */\n\n// JWT as a string, read from where-ever:\n$jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';\n\ntry {\n    \n    $webhook = Webhook::constructFromJWT($jwt, 'my_jwt_secret');\n    \n} catch (\\nickdnk\\GatewayAPI\\Exceptions\\WebhookException $exception) {\n    \n    $exception-\u003egetMessage();\n    \n}\n```\n#### Example #4: Handling SMSMessages or Recipients as JSON\n`SMSMessage` and `Recipient` are encoded into the the actual JSON sent\nto the API. If you put this output into a queue, or anything similar,\nand want them back as PHP objects later, you can use these methods to\ndo so.\n```php\nuse nickdnk\\GatewayAPI\\Entities\\Request\\Recipient;\nuse nickdnk\\GatewayAPI\\Entities\\Request\\SMSMessage;\n\n$recipient = new Recipient(4587652222, ['Martha', '42442']);\n\n$json = json_encode($recipient);\n\n$recipient = Recipient::constructFromJSON($json);\n\n$message = new SMSMessage('Hello %NAME%! Your code is: %CODE%', 'MyService');\n$message-\u003esetSendTime(time() + 3600);\n$message-\u003esetUserReference('reference');\n$message-\u003esetTags(['%NAME%', '%CODE%']);\n$message-\u003eaddRecipient($recipient);\n\n$json = json_encode($message);\n\n$smsMessage = SMSMessage::constructFromJSON($json);\n$smsMessage-\u003egetMessage();\n$smsMessage-\u003egetRecipients();\n```\n\n### Tests\n\nIf you want to run the unit tests that don't require credentials, simply\nrun `vendor/bin/phpunit` from the root of the project.\n\nIf you want to test the parts that interact with the API you must\nprovide credentials in `GatewayAPIHandlerTest.php` and run the above\ncommand. Note that this sends out live SMS and will cost you 1 SMS in\ncredits per execution.\n\n### Contact\n\nYou can reach me at nickdnk@hotmail.com.\n\nUse this library at your own risk. PRs are welcome :)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickdnk%2Fgatewayapi-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnickdnk%2Fgatewayapi-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickdnk%2Fgatewayapi-php/lists"}