Repository navigation
Project Structure
The project is a standard Laravel 8 application with two additions: a small Selldone\provider PHP library that parses and verifies webhooks, and a Vue 2 + Vuetify panel built with Laravel Mix. This page maps the files you will touch when you turn the sample into your own bridge.
sample-connect-provider/
├── app/Http/Controllers/
│ ├── Controller.php # CLIENT_ID, CLIENT_SECRET, sample code/token, newProviderClient()
│ ├── AuthorizationController.php # login, accept, reject, token
│ ├── WebhooksController.php # 7 webhook handlers with sample data
│ └── PagesController.php # renders the panel and injects window.SD_CONFIG
├── config/selldone.php # SD_PROVIDER_* settings
├── routes/
│ ├── web.php # /auth/* routes + catch-all for the Vue panel
│ └── api.php # /api/* webhook routes
├── selldone/provider/ # Selldone\provider library (PSR-4 "Selldone\\" => "selldone/")
│ ├── ProviderClient.php
│ ├── enums/ # ProductType, ProductStatus, ProductCondition, PriceInputType, ProductPricing
│ ├── errors/ErrorResponse.php
│ └── webhook/
│ ├── Webhooks.php # signature verification + on…() factories
│ ├── WebhookAbstract.php # reads the Authorization header
│ ├── WebhookNotifyShop.php, WebhookSyncCategories.php, WebhookSyncProducts.php,
│ │ WebhookCreateOrder.php, WebhookConfirmOrder.php, WebhookGetOrder.php, WebhookCancelOrder.php
│ ├── models/ # WebhookProduct, WebhookVariant, WebhookCategory, WebhookRecipient, ...
│ └── responses/ # SyncCategoriesResponse, SyncProductsResponse, UpdateOrderResponse
├── resources/
│ ├── views/ # index.blade.php (panel), login.blade.php (grant/reject), error.blade.php
│ └── js/
│ ├── app.js, App.vue, router/Router.js, store/Store.js, plugins/vuetify.js
│ ├── pages/ # Home, Webhooks, APIs, Auth, Help
│ ├── components/ # ApiBox, LinkBoxCopy
│ └── enums/ # ConnectMode, ConnectScope, ProviderWebhooks, ProviderAuthenticationMode
├── art/ # README images
├── webpack.mix.js # resources/js/app.js -> public/js, resources/sass/app.scss -> public/css
└── START SERVER.bat # php artisan serve --port=10000
Holds the sample OAuth client (CLIENT_ID, CLIENT_SECRET), a fixed SAMPLE_AUTHENTICATION_CODE and SAMPLE_ACCESS_TOKEN, and the factory:
protected static function newProviderClient(): ProviderClient
{
return new ProviderClient(
config('selldone.provider-webhook-sign-key'),
config('selldone.provider-secret-key')
);
}The catch-all route GET /{any?} renders index.blade.php with a $config array that becomes window.SD_CONFIG in the browser. It contains the return URL, sign key, secret key, client ID/secret, login and token URLs, all webhook URLs, the provider API URL and the sample access token. This exposes secrets to the browser and exists only for learning.
ProviderClient::webhook($request) returns a Webhooks object, which verifies the signature in its constructor. Call one on…() method to parse the specific webhook; each parser validates its payload with Laravel's validator and throws an Exception with a 400 or 403 code on failure. ErrorResponse::Exception($e) turns that exception into an HTTP response. See Webhooks.
| Page | Route | Shows |
|---|---|---|
| Home | / |
Service mode (Migration), auth mode (OAuth 2.0), webhook sign key, API secret key. |
| Webhooks | /webhooks |
Explanation of the signature headers and every webhook URL to copy. |
| APIs | /apis |
Tester for the provider API (see Provider API). |
| Auth | /auth |
OAuth steps plus return URL, client ID/secret, login URL and token URL to copy. |
| Help | /help |
Setup steps with screenshots. |
Build commands (from package.json): npm run dev, npm run watch, npm run hot, npm run prod.
- Replace the constants in
Controller.phpwith real client credentials stored in configuration. - Implement real login, consent, code and token handling in
AuthorizationController.php. - Replace the sample data in
WebhooksController.phpwith data from your service, looked up by the access token. - Remove
window.SD_CONFIGsecrets fromindex.blade.php(or drop the panel entirely). - Keep the
Selldone\providerlibrary for signature verification and payload parsing.