Skip to content
Docs menu: Connect a store

Connect a store

Guides

A store never holds a vendor’s secret key. Its owner approves it on a Tallio page, and the store’s server exchanges a one-time code for its restricted keys, bound to one merchant.

On this page

Important

Keep the store’s keys sealed on its server: never in a URL, a page or the browser. A restricted key (rk_live_…, rk_test_…) acts for its own merchant only, and only through the operations listed below.

The grant #

Connect to Tallio is an OAuth 2.0 authorization code grant with PKCE (S256). The code travels in the browser; the verifier never leaves the store’s server, so a code alone is useless.

  • Ask. The store keeps a random state and a code_verifier (43 to 128 characters), and sends its admin’s browser to Tallio’s hosted page with the challenge. redirect_uri must be exactly the store’s callback under its URL, nothing else.
  • Consent. The admin signs in to Tallio, or signs up, and an owner of the team approves the store, confirming with a second factor or a fresh sign-in. On a first connect they also type the business’s tax ids, and Tallio creates its merchant.
  • Return. The browser comes back to redirect_uri with code and the same state, or with error=access_denied when the admin cancels. The code lives 10 minutes.
  • Exchange. The store’s server calls POST /store_grants/token with the code, the verifier and the same redirect_uri, naming itself in Tallio-Store-Url. The answer, given once, holds the merchant, the team, the two keys and the secrets of the store’s webhook endpoints.
Send the admin’s browser to
GET /dashboard/connect-store
  ?platform=woocommerce
  &store_url=https://shop.example
  &redirect_uri=https%3A%2F%2Fshop.example%2Fwp-admin%2Fadmin.php%3Fpage%3Dtallio-connect
  &state=…
  &code_challenge=…
  &code_challenge_method=S256
  &locale=el
Exchange the code, from the store’s server
curl "$TALLIO_API_URL/v1/store_grants/token" \
  -H "Tallio-Store-Url: https://shop.example" \
  -H "Content-Type: application/json" \
  -d '{"grant_type":"authorization_code","code":"…","code_verifier":"…","redirect_uri":"https://shop.example/wp-admin/admin.php?page=tallio-connect","store_environment":"production"}'

Every refused exchange is the same 400 invalid_grant, whatever the cause. Never retry a successful exchange: exchanging a spent code again with its verifier revokes the keys it made, since a replay means the code leaked. After a lost answer, connect again.

The hosted page’s language #

Pass the admin’s language in locale (el, fr_FR, en_US): sign-in and the consent page follow it when Tallio speaks it, for that session only. An unknown or missing value never refuses the request.

Live and test keys #

The exchange always answers a test key, and a live key only for a production store. Send store_environment (production, staging, development, local): anything but production gets a test key only, as does a development host (localhost, .test, a private address, a public tunnel). A test key issues through the merchant’s test connection, or Tallio’s sandbox when there is none.

The store’s URL #

A store’s keys are bound to its URL. Send it in Tallio-Store-Url on every call: another value, or none, is 409 store_url_mismatch. It keeps a staging copy of the store from issuing live with copied settings; it is not a secret. When the store really moved, its admin confirms the move and the store sends its new URL to PUT /store_binding; while the store has a live key, only that key may move it.

What a store key can call #

A store key reaches only the operations in the table below, and only for its own merchant: another merchant’s ids answer 404, as if they did not exist. Any other operation is 403 restricted_key: a store key cannot create merchants, list events, manage webhook endpoints or keys, or reach the MCP server.

When the store disconnects or the plugin is removed, the store gives up each key with DELETE /api_keys/current. A team owner can also revoke the store’s keys from the dashboard; a new connection replaces the old keys.

Store key operations #

Generated from the API’s operation registry, the list the API checks every store key against.

Operations a store key may call
OperationCall
Retrieve a documentGET /documents/{id}
Download a document's PDFGET /documents/{id}/pdf
Retrieve a merchantGET /merchants/{id}
Erase a customer's dataPOST /erasures
Send a shop orderPOST /store_orders
Retrieve a store orderGET /store_orders/{id}
List store ordersGET /store_orders
Retry a store orderPOST /store_orders/{id}/retry
Mark a store order handledPOST /store_orders/{id}/mark_handled
Review a waiting invoicePOST /store_orders/{id}/invoice_review
Confirm a waiting invoicePOST /store_orders/{id}/confirm_invoice
Correct a store order's documentPOST /store_orders/{id}/correct
Cancel a store order's documentPOST /store_orders/{id}/cancel
Save a buyer's invoice requestPUT /store_orders/{id}/invoice_request
Send a refund of a store orderPOST /store_orders/{id}/refunds
Mark a store refund handledPOST /store_orders/{id}/refunds/{refundId}/mark_handled
Retrieve a merchant's store settingsGET /merchants/{id}/store_settings
Update a merchant's store settingsPATCH /merchants/{id}/store_settings
Retrieve the store plan's usageGET /store_usage
List a merchant's connectionsGET /merchants/{id}/connections
Retrieve a connectionGET /connections/{id}
Create a hosted connect linkPOST /merchants/{id}/connect_sessions
Look up a VAT numberGET /tax_ids/lookup
Revoke the key making this requestDELETE /api_keys/current
Confirm that the store moved to a new URLPUT /store_binding