OAuth Integration
Build secure integrations with Shoporama API using OAuth 2.0
What is OAuth?
OAuth allows external applications to securely access the Shoporama API on behalf of your users without sharing their login credentials.
Safe
No sharing of passwords. Users log in directly to Shoporama
Nem integration
Standard OAuth 2.0 flow that you know from other services
Flexible
Choose exactly what rights your app should have
OAuth Flow - Step by step
Send user to Shoporama
Your app sends the user to Shoporama's OAuth endpoint
https://www.shoporama.dk/admin/oauth/login?
client_id=Din_App_Navn
redirect_uri=https://example.com/callback
state=unik_session_id
User logs in
The user logs in with their Shoporama credentials and selects:
- Which shop to give access to
- Access Level (Read, Write, or Full)
The token is linked to the user. If the user has been assigned a role other than "Full Access" in the online store, the token can only perform the actions permitted by that role, regardless of the access level. See " Access Level" and "User Role."
Receive API token
After authentication, the user is sent back to your app with the token:
https://example.com/callback?
token=f06cb746684f936270bf...
shop_url=demo.shoporama.dk
shop_name=Demo Shop
api_endpoint=https://www.shoporama.dk/REST
webshop_id=1
access_level=all
state=unik_session_id
Use the API
Use the token to call the Shoporama API:
curl -H "Authorization: f06cb746684f936270bf..." \
https://www.shoporama.dk/REST/product
Ready to get started?
Start by testing the OAuth flow or read more about the API
Complete Implementation Examples
Full OAuth flow implementation - copy/paste ready
Vanilla PHP Implementation
Pure PHP without frameworks - a single file that handles the entire OAuth flow
<?php
// oauth.php - Gem denne fil på din server
session_start();
// Konfiguration - RET DISSE VÆRDIER
$CLIENT_ID = "Dit App Navn";
$REDIRECT_URI = "https://din-side.dk/oauth.php";
$OAUTH_URL = "https://www.shoporama.dk/admin/oauth/login";
// Start OAuth
if (isset($_GET["login"])) {
$_SESSION["state"] = bin2hex(random_bytes(16));
$url = $OAUTH_URL . "?" . http_build_query([
"client_id" => $CLIENT_ID,
"redirect_uri" => $REDIRECT_URI,
"state" => $_SESSION["state"]
]);
header("Location: $url");
exit;
}
// Modtag token
if (isset($_GET["token"]) && $_GET["state"] === $_SESSION["state"]) {
$_SESSION["token"] = $_GET["token"];
$_SESSION["api_url"] = $_GET["api_endpoint"];
echo "Success! Token gemt.";
echo "
Test API";
exit;
}
// Test API
if (isset($_GET["test"]) && isset($_SESSION["token"])) {
$ch = curl_init($_SESSION["api_url"] . "/product?limit=1");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: " . $_SESSION["token"]]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
echo "" . htmlspecialchars($result) . "
";
exit;
}
// Start side
echo "Login med Shoporama";
?>
How to use it:
- Copy the code to a file called
oauth.php - Correct
$CLIENT_IDand$REDIRECT_URI - Upload the file to your server
- Visit the page and click "Login with Shoporama"
Troubleshooting & Common issues
Common OAuth errors
access_denied
The user was denied access. Show a friendly message and let them try again.
invalid_client
Unknown client_id. Check that your app name is correct.
invalid_redirect_uri
Redirect URI does not match. Must be the exact same URL.
state_mismatch
State parameter does not match. Possible CSRF attack or session timeout.
API errors
401 Unauthorized
The token is invalid, has expired, or has been revoked—for example, because the user has been removed from the store. Ask the user to log in again. If the user has been removed from the store, another user with access to the store must link the app.
403 Forbidden
The token must not make the call. The "error" field in the response is "insufficient_scope" if the access level does not permit the method, and "insufficient_role" if the role of the user behind the token does not grant access. The "message" field explains why.
429 Too Many Requests
Rate limit reached. Please wait until the next request.
500 Server Error
Internal error. Please try again later or contact support.
Debug tips
Test with OAuth Test Client
Use our test client to verify your OAuth flow is working correctly.
Test OAuth Flow →Log all parameters
Log state, token and other parameters to debug issues.
Safety & Best Practices
Token storage
- • Never store tokens in cookies or localStorage
- • Use server-side sessions or encrypted database
- • Encrypt tokens before storage
- • Delete tokens when they are no longer used
CSRF protection
- • Always use state parameter
- • Generate unique state for each session
- • Verify state in callback
- • Timeout state after a short time
HTTPS required
- • Only use HTTPS for redirect_uri
- • All API calls must be over HTTPS
- • Exception: localhost for development
- • Check SSL certificate validity
Access levels explained
| Level | Description | Allowed | Not allowed |
|---|---|---|---|
| read | Read access to data | GET requests | POST, PUT, DELETE requests |
| write | Create, modify, and delete data | POST, PUT, DELETE requests | GET requests |
| all | Read and write data | All HTTP methods | – |
Recommendation: Start with 'read' access during development and only upgrade to 'write' or 'all' when necessary for your application's functionality.
On the login page, the levels are Read, Write, and All. The user's role may further restrict the token; see " Access Level and User Role " below.
Access Level and User Role
The access level determines which HTTP methods the token is allowed to use. The token is also linked to the user who authorized the access. If the user has been assigned a role other than Full Access on the online store—such as Employee, Marketing, or Developer—the token can only perform the actions permitted by that role, regardless of the access level. This means:
- GET requires that the role be able to view the area, such as orders or products. POST, PUT, and DELETE require that the role be able to edit it.
- Statistics (statistics and top products) require the "Revenue and Statistics" add-on.
- To adjust cost prices, you need the “Cost Prices and Markup” add-on. The same applies to inventory settings (minimum inventory and cost price, both for retrieving and adjusting them) and updating the inventory value. The reports on markup, ABC analysis, and inventory turnover require both this add-on and the “Sales and Statistics” add-on. Without this add-on, cost prices and figures calculated based on them (e.g., markup and inventory value) are removed from the results.
- Deleting products, orders, and customers requires the "Deletion and Bulk Import" add-on. Bulk import also requires this add-on—that is, a POST request containing a list of products or customers.
- Crediting, canceling, and changing the payment status of orders require the "Refunds and Cancellations" add-on.
- The "Supplier" role can only retrieve, edit, copy, and restore individual products by ID; using the "Delete" function and bulk import, they can also delete them, as well as retrieve and upload images to the image archive. If a supplier has been selected for the user, this applies only to the supplier’s own products. Product lists and brand-new products are managed in the admin panel.
- If the user is logged out of the online store, the token is revoked, and the call returns a 401 error.
Users who still have the configuration from before the roles were introduced (the former "Order Management" and "Supplier" checkboxes) will not be restricted until the company administrator selects or changes their role.
The parameters your app receives after authorization do not indicate the user's role. A restriction only becomes apparent when a request is rejected with a 403 error and a response like this:
{
"error": "insufficient_role",
"message": "The user behind this token has the role 'Marketing' on this webshop, which does not allow PUT order. Ask the company administrator to change the role.",
"method": "PUT",
"path": "order/123",
"role": ["marketing"],
"option": null
}
The "role" field shows the user's role, such as "staff," "marketing," or "developer." The "option" field shows the option that the role lacks, such as "refund." If "option" is null, the role does not grant access to the resource or method at all.
The "Full" access level on the login page is not the same as the "Full Access" role. If you want your app to have full capabilities, a user with the "Full Access" role must approve the access. You can find all the rules in the API documentation, and the roles are described in " Roles and Permissions."
Complete API documentation
See all available endpoints, methods and parameters in our REST API documentation
See API Documentation