oauth-examples
Authentication required before calling the OAuth API endpoints
These examples assume your backend has already authenticated with Noon using your integrator service account credentials and is reusing that authenticated client or session when calling POST /identity/oauth/v1/token/create and POST /identity/oauth/v1/token/exchange.
The OAuth client_id and client_secret shown in the request body identify your OAuth application, but they do not replace the authenticated integrator session. For the standard login flow, see Authenticating Your Requests.
- Python
- Go
- Node.js
- PHP
- Java
- .NET
- Curl/Bash
import json
import uuid
import requests
from flask import Flask, request, session, redirect
app = Flask(__name__)
app.secret_key = 'your-secret-key-here' # Use a secure secret key
# Load your OAuth client credentials
CLIENT_ID = 'your_client_id'
CLIENT_SECRET = 'your_client_secret'
# Step 1: Initiate OAuth flow - redirect user to authorization URL
@app.route('/connect-seller')
def connect_seller():
# Generate and store state for CSRF protection
state = str(uuid.uuid4())
session['oauth_state'] = state
authorization_url = f"https://oauth.noon.partners/?client_id={CLIENT_ID}&state={state}"
return redirect(authorization_url)
# Step 2: Handle callback and verify state
@app.route('/oauth/callback')
def oauth_callback():
# Verify state parameter to prevent CSRF attacks
received_state = request.args.get('state')
stored_state = session.get('oauth_state')
if not received_state or received_state != stored_state:
return "Invalid state parameter - possible CSRF attack", 400
# Clear the stored state
session.pop('oauth_state', None)
# Get authorization code
authorization_code = request.args.get('code')
if not authorization_code:
return "No authorization code received", 400
try:
# Step 3: Exchange authorization code for access token
token_response = get_access_token(authorization_code)
print(f"Access token obtained for project: {token_response['project_code']}")
# Step 4: Exchange access token to create service account and receive credentials
sa_response = create_service_account(token_response['access_token'])
credentials = sa_response['result']
print(f"Credentials received for project: {token_response['project_code']}")
# Store credentials['private_key'] securely — it is only returned once
return f"Successfully connected seller project: {token_response['project_code']}"
except Exception as e:
return f"Error: {e}", 500
# Step 3: Exchange authorization code for access token
def get_access_token(auth_code):
url = 'https://noon-api-gateway.noon.partners/identity/oauth/v1/token/create'
payload = {
'grant_type': 'authorization_code',
'code': auth_code,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET
}
response = requests.post(url, json=payload, headers={
'Content-Type': 'application/json',
'User-Agent': 'YourApp/1.0'
})
if response.status_code == 200:
return response.json()
else:
raise Exception(f"Failed to get access token: {response.text}")
# Step 4: Exchange access token to create service account and receive credentials
def create_service_account(access_token):
url = 'https://noon-api-gateway.noon.partners/identity/oauth/v1/token/exchange'
payload = {
'access_token': access_token
}
response = requests.post(url, json=payload, headers={
'Content-Type': 'application/json',
'User-Agent': 'YourApp/1.0'
})
if response.status_code == 200:
return response.json()
else:
raise Exception(f"Failed to create service account: {response.text}")
if __name__ == '__main__':
app.run(debug=True)
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
const (
ClientID = "your_client_id"
ClientSecret = "your_client_secret"
BaseURL = "https://noon-api-gateway.noon.partners/identity/oauth/v1"
)
type TokenRequest struct {
GrantType string `json:"grant_type"`
Code string `json:"code"`
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
}
type TokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn string `json:"expires_in"`
Scopes []string `json:"scopes"`
ProjectCode string `json:"project_code"`
}
type ExchangeRequest struct {
AccessToken string `json:"access_token"`
}
type ExchangeResponse struct {
Status struct {
Code int `json:"code"`
Message string `json:"message"`
} `json:"status"`
ProjectCode string `json:"project_code"`
}
func getAccessToken(authCode string) (*TokenResponse, error) {
reqBody := TokenRequest{
GrantType: "authorization_code",
Code: authCode,
ClientID: ClientID,
ClientSecret: ClientSecret,
}
jsonData, err := json.Marshal(reqBody)
if err != nil {
return nil, err
}
resp, err := http.Post(
BaseURL+"/token/create",
"application/json",
bytes.NewBuffer(jsonData),
)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("failed to get token: %s", string(body))
}
var tokenResp TokenResponse
if err := json.NewDecoder(resp.Body).Decode(&tokenResp); err != nil {
return nil, err
}
return &tokenResp, nil
}
func createServiceAccount(accessToken string) (*ExchangeResponse, error) {
reqBody := ExchangeRequest{
AccessToken: accessToken,
}
jsonData, err := json.Marshal(reqBody)
if err != nil {
return nil, err
}
resp, err := http.Post(
BaseURL+"/token/exchange",
"application/json",
bytes.NewBuffer(jsonData),
)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("failed to create service account: %s", string(body))
}
var exchangeResp ExchangeResponse
if err := json.NewDecoder(resp.Body).Decode(&exchangeResp); err != nil {
return nil, err
}
return &exchangeResp, nil
}
func main() {
// Step 1: Direct user to authorization URL
authURL := fmt.Sprintf(
"https://oauth.noon.partners/?client_id=%s&state=%s",
ClientID,
uuid.New().String(),
)
fmt.Printf("Direct user to: %s\n", authURL)
// Step 2: Receive authorization code from callback
authCode := "AUTHORIZATION_CODE_FROM_CALLBACK"
// Step 3: Get access token
tokenResp, err := getAccessToken(authCode)
if err != nil {
fmt.Printf("Error getting access token: %v\n", err)
return
}
fmt.Printf("Access token obtained for project: %s\n", tokenResp.ProjectCode)
// Step 4: Create service account
saResp, err := createServiceAccount(tokenResp.AccessToken)
if err != nil {
fmt.Printf("Error creating service account: %v\n", err)
return
}
fmt.Printf("Service account created for project: %s\n", saResp.ProjectCode)
}
import express from "express";
import session from "express-session";
import axios from "axios";
import { randomBytes } from "crypto";
const app = express();
const CLIENT_ID = "your_client_id";
const CLIENT_SECRET = "your_client_secret";
const BASE_URL = "https://noon-api-gateway.noon.partners/identity/oauth/v1";
// Setup session middleware
app.use(session({
secret: 'your-secret-key-here',
resave: false,
saveUninitialized: false,
cookie: { secure: false } // Set to true in production with HTTPS
}));
// Step 1: Initiate OAuth flow
app.get('/connect-seller', (req, res) => {
// Generate and store state for CSRF protection
const state = randomBytes(16).toString('hex');
req.session.oauthState = state;
const authUrl = `https://oauth.noon.partners/?client_id=${CLIENT_ID}&state=${state}`;
res.redirect(authUrl);
});
// Step 2: Handle OAuth callback
app.get('/oauth/callback', async (req, res) => {
// Verify state parameter
const receivedState = req.query.state;
const storedState = req.session.oauthState;
if (!receivedState || receivedState !== storedState) {
return res.status(400).send('Invalid state parameter - possible CSRF attack');
}
// Clear stored state
delete req.session.oauthState;
const authCode = req.query.code;
if (!authCode) {
return res.status(400).send('No authorization code received');
}
try {
// Step 3: Exchange code for access token
const tokenResponse = await getAccessToken(authCode);
console.log(`Access token obtained for project: ${tokenResponse.project_code}`);
// Step 4: Create service account
const saResponse = await createServiceAccount(tokenResponse.access_token);
console.log('Service account created:', saResponse);
res.send(`Successfully connected seller project: ${tokenResponse.project_code}`);
} catch (error) {
console.error('Error:', error.message);
res.status(500).send(`Error: ${error.message}`);
}
});
// Step 3: Exchange authorization code for access token
async function getAccessToken(authCode) {
try {
const response = await axios.post(
`${BASE_URL}/token/create`,
{
grant_type: "authorization_code",
code: authCode,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
},
{
headers: {
"Content-Type": "application/json",
"User-Agent": "YourApp/1.0",
},
}
);
return response.data;
} catch (error) {
throw new Error(`Failed to get access token: ${error.response?.data || error.message}`);
}
}
// Step 4: Exchange access token to create service account
async function createServiceAccount(accessToken) {
try {
const response = await axios.post(
`${BASE_URL}/token/exchange`,
{
access_token: accessToken,
},
{
headers: {
"Content-Type": "application/json",
"User-Agent": "YourApp/1.0",
},
}
);
return response.data;
} catch (error) {
throw new Error(`Failed to create service account: ${error.response?.data || error.message}`);
}
}
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
console.log('Visit http://localhost:3000/connect-seller to start OAuth flow');
});
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$clientId = "your_client_id";
$clientSecret = "your_client_secret";
$baseUrl = "https://noon-api-gateway.noon.partners/identity/oauth/v1";
// Step 1: Initiate OAuth flow
// Generate state and store it in session for CSRF protection
session_start();
$state = bin2hex(random_bytes(16));
$_SESSION['oauth_state'] = $state;
$authUrl = sprintf(
"https://oauth.noon.partners/?client_id=%s&state=%s",
$clientId,
$state
);
// Redirect user to this URL
header("Location: " . $authUrl);
exit();
// Step 2: Handle OAuth callback (in your callback endpoint)
// Verify state parameter
session_start();
$receivedState = $_GET['state'] ?? '';
$storedState = $_SESSION['oauth_state'] ?? '';
if (empty($receivedState) || $receivedState !== $storedState) {
die("Invalid state parameter - possible CSRF attack");
}
// Clear stored state
unset($_SESSION['oauth_state']);
// Get authorization code
$authorizationCode = $_GET['code'] ?? '';
if (empty($authorizationCode)) {
die("No authorization code received");
}
$client = new Client();
try {
// Step 3: Exchange authorization code for access token
$tokenResponse = $client->post($baseUrl . '/token/create', [
'json' => [
'grant_type' => 'authorization_code',
'code' => $authorizationCode,
'client_id' => $clientId,
'client_secret' => $clientSecret,
],
'headers' => [
'Content-Type' => 'application/json',
'User-Agent' => 'YourApp/1.0',
]
]);
$tokenData = json_decode($tokenResponse->getBody(), true);
echo "Access token obtained for project: " . $tokenData['project_code'] . "\n";
// Step 4: Exchange access token to create service account
$saResponse = $client->post($baseUrl . '/token/exchange', [
'json' => [
'access_token' => $tokenData['access_token'],
],
'headers' => [
'Content-Type' => 'application/json',
'User-Agent' => 'YourApp/1.0',
]
]);
$saData = json_decode($saResponse->getBody(), true);
echo "Service account created: " . json_encode($saData) . "\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
package com.noon.oauth;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import java.io.IOException;
public class OAuthExample {
private static final String CLIENT_ID = "your_client_id";
private static final String CLIENT_SECRET = "your_client_secret";
private static final String BASE_URL = "https://noon-api-gateway.noon.partners/identity/oauth/v1";
private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
private final OkHttpClient client = new OkHttpClient();
private final ObjectMapper mapper = new ObjectMapper();
public static class TokenRequest {
public String grant_type = "authorization_code";
public String code;
public String client_id;
public String client_secret;
}
public static class TokenResponse {
public String access_token;
public String token_type;
public String expires_in;
public String[] scopes;
public String project_code;
}
public static class ExchangeRequest {
public String access_token;
}
public static class ExchangeResponse {
public static class Status {
public int code;
public String message;
}
public Status status;
public String project_code;
}
public TokenResponse getAccessToken(String authCode) throws IOException {
TokenRequest req = new TokenRequest();
req.code = authCode;
req.client_id = CLIENT_ID;
req.client_secret = CLIENT_SECRET;
String json = mapper.writeValueAsString(req);
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(BASE_URL + "/token/create")
.post(body)
.addHeader("User-Agent", "YourApp/1.0")
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Failed to get token: " + response);
}
return mapper.readValue(response.body().string(), TokenResponse.class);
}
}
public ExchangeResponse createServiceAccount(String accessToken) throws IOException {
ExchangeRequest req = new ExchangeRequest();
req.access_token = accessToken;
String json = mapper.writeValueAsString(req);
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(BASE_URL + "/token/exchange")
.post(body)
.addHeader("User-Agent", "YourApp/1.0")
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Failed to create service account: " + response);
}
return mapper.readValue(response.body().string(), ExchangeResponse.class);
}
}
public static void main(String[] args) {
// Step 1: Initiate OAuth flow
// Generate state and store it (e.g., in session/database) for CSRF protection
String state = UUID.randomUUID().toString();
// IMPORTANT: Store this state value to verify later in callback
// Example: session.setAttribute("oauth_state", state);
String authUrl = String.format(
"https://oauth.noon.partners/?client_id=%s&state=%s",
CLIENT_ID,
state
);
// Redirect user to authUrl
System.out.println("Redirect user to: " + authUrl);
// Step 2: Handle OAuth callback (in your callback endpoint)
// IMPORTANT: Verify state parameter matches stored value
// String receivedState = request.getParameter("state");
// String storedState = (String) session.getAttribute("oauth_state");
// if (!receivedState.equals(storedState)) {
// throw new SecurityException("Invalid state - possible CSRF attack");
// }
String authCode = "AUTHORIZATION_CODE_FROM_CALLBACK";
OAuthExample oauth = new OAuthExample();
try {
// Step 3: Get access token
TokenResponse tokenResp = oauth.getAccessToken(authCode);
System.out.println("Access token obtained for project: " + tokenResp.project_code);
// Step 4: Create service account
ExchangeResponse saResp = oauth.createServiceAccount(tokenResp.access_token);
System.out.println("Service account created for project: " + saResp.project_code);
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
}
}
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class OAuthExample
{
private const string ClientId = "your_client_id";
private const string ClientSecret = "your_client_secret";
private const string BaseUrl = "https://noon-api-gateway.noon.partners/identity/oauth/v1";
private static readonly HttpClient client = new HttpClient();
public class TokenRequest
{
public string grant_type { get; set; } = "authorization_code";
public string code { get; set; }
public string client_id { get; set; }
public string client_secret { get; set; }
}
public class TokenResponse
{
public string access_token { get; set; }
public string token_type { get; set; }
public string expires_in { get; set; }
public string[] scopes { get; set; }
public string project_code { get; set; }
}
public class ExchangeRequest
{
public string access_token { get; set; }
}
public class ExchangeResponse
{
public class StatusInfo
{
public int code { get; set; }
public string message { get; set; }
}
public StatusInfo status { get; set; }
public string project_code { get; set; }
}
static async Task<TokenResponse> GetAccessToken(string authCode)
{
var request = new TokenRequest
{
code = authCode,
client_id = ClientId,
client_secret = ClientSecret
};
var json = JsonSerializer.Serialize(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"{BaseUrl}/token/create", content);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<TokenResponse>(responseBody);
}
static async Task<ExchangeResponse> CreateServiceAccount(string accessToken)
{
var request = new ExchangeRequest
{
access_token = accessToken
};
var json = JsonSerializer.Serialize(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"{BaseUrl}/token/exchange", content);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<ExchangeResponse>(responseBody);
}
static async Task Main(string[] args)
{
// Step 1: Initiate OAuth flow
// Generate state and store it (e.g., in session) for CSRF protection
var state = Guid.NewGuid().ToString();
// IMPORTANT: Store this state value to verify later in callback
// Example: HttpContext.Session.SetString("oauth_state", state);
var authUrl = $"https://oauth.noon.partners/?client_id={ClientId}&state={state}";
// Redirect user to authUrl
Console.WriteLine($"Redirect user to: {authUrl}");
// Step 2: Handle OAuth callback (in your callback endpoint)
// IMPORTANT: Verify state parameter matches stored value
// var receivedState = Request.Query["state"];
// var storedState = HttpContext.Session.GetString("oauth_state");
// if (receivedState != storedState) {
// throw new SecurityException("Invalid state - possible CSRF attack");
// }
var authCode = "AUTHORIZATION_CODE_FROM_CALLBACK";
try
{
// Step 3: Get access token
var tokenResponse = await GetAccessToken(authCode);
Console.WriteLine($"Access token obtained for project: {tokenResponse.project_code}");
// Step 4: Create service account
var saResponse = await CreateServiceAccount(tokenResponse.access_token);
Console.WriteLine($"Service account created for project: {saResponse.project_code}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
#!/usr/bin/env bash
CLIENT_ID="your_client_id"
CLIENT_SECRET="your_client_secret"
BASE_URL="https://noon-api-gateway.noon.partners/identity/oauth/v1"
# Step 1: Initiate OAuth flow
# Generate state and store it for CSRF protection
STATE=$(uuidgen)
# IMPORTANT: Store this state value (e.g., in Redis, file, or database)
# to verify later in callback. Example:
# echo "$STATE" > /tmp/oauth_state_${USER_ID}
AUTH_URL="https://oauth.noon.partners/?client_id=${CLIENT_ID}&state=${STATE}"
echo "Redirect user to: ${AUTH_URL}"
# Step 2: Handle OAuth callback (in your callback handler)
# IMPORTANT: Verify state parameter matches stored value
# RECEIVED_STATE="..." # Extract from callback URL
# STORED_STATE=$(cat /tmp/oauth_state_${USER_ID})
# if [ "$RECEIVED_STATE" != "$STORED_STATE" ]; then
# echo "Invalid state - possible CSRF attack"
# exit 1
# fi
AUTH_CODE="AUTHORIZATION_CODE_FROM_CALLBACK"
# Step 3: Exchange authorization code for access token
TOKEN_RESPONSE=$(curl -s -X POST "${BASE_URL}/token/create" \
-H "Content-Type: application/json" \
-H "User-Agent: YourApp/1.0" \
-d "{
\"grant_type\": \"authorization_code\",
\"code\": \"${AUTH_CODE}\",
\"client_id\": \"${CLIENT_ID}\",
\"client_secret\": \"${CLIENT_SECRET}\"
}")
# Extract access token
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')
PROJECT_CODE=$(echo "$TOKEN_RESPONSE" | jq -r '.project_code')
echo "Access token obtained for project: ${PROJECT_CODE}"
# Step 4: Exchange access token to create service account
SA_RESPONSE=$(curl -s -X POST "${BASE_URL}/token/exchange" \
-H "Content-Type: application/json" \
-H "User-Agent: YourApp/1.0" \
-d "{
\"access_token\": \"${ACCESS_TOKEN}\"
}")
echo "Service account created: ${SA_RESPONSE}"