A quick post that might help someone else out when using the Sitecore Order Cloud dotnet SDK. When I started playing around with the SDK, I struggled to get it talking to OrderCloud successfully.

I ran code like below in my test application (i.e. Linqpad):

using OrderCloud.SDK;

// ...
// ...

using var client = new OrderCloudClient(new OrderCloudClientConfig()
{
    ApiUrl = "https://sandboxapi.ordercloud.io",
    ClientId = _clientId,
    ClientSecret = _clientSecret
    Roles = new[] {
        ApiRole.BuyerReader,
            ApiRole.CatalogAdmin,
            ApiRole.MeAdmin,
            ApiRole.AdminUserAdmin,
            ApiRole.OrderAdmin,
            ApiRole.PasswordReset,
            ApiRole.PriceScheduleAdmin,
            ApiRole.ProductAdmin,
            ApiRole.ProductAssignmentAdmin,
            ApiRole.ShipmentAdmin
    }
});

var me = await client.Me.GetAsync();

And got an invalid_client exception back. Invalid client exception

It took me a little while to realise that the URL in the exception was not the sandbox one, so I needed to specify it in the configuration. Of course the client_id is invalid, because it doesn’t exist in production!

The working code is shown below.

using OrderCloud.SDK;

// ...
// ...

using var client = new OrderCloudClient(new OrderCloudClientConfig()
{
    ApiUrl = "https://sandboxapi.ordercloud.io", //must define this for sandbox
    AuthUrl = "https://sandboxapi.ordercloud.io", //must define this for sandbox
    ClientId = _clientId,
    ClientSecret = _clientSecret,
    Roles = new[] {
        ApiRole.BuyerReader,
            ApiRole.CatalogAdmin,
            ApiRole.MeAdmin,
            ApiRole.AdminUserAdmin,
            ApiRole.OrderAdmin,
            ApiRole.PasswordReset,
            ApiRole.PriceScheduleAdmin,
            ApiRole.ProductAdmin,
            ApiRole.ProductAssignmentAdmin,
            ApiRole.ShipmentAdmin
    }
});

var me = await client.Me.GetAsync();

The result is

{
  "Buyer": {
    "ID": "BUYER_ORGANIZATION",
    "DefaultCatalogID": "BUYER_ORGANIZATION"
  },
  "Supplier": null,
  "Seller": {
    "ID": "xxxxxxxxxxx"
  },
  "ID": "BUYER_USER",
  "Username": "buyer01",
  "Password": null,
  "FirstName": "Buyer",
  "LastName": "User",
  "Email": "[email protected]",
  "Phone": null,
  "TermsAccepted": null,
  "Active": true,
  "xp": null,
  "AvailableRoles": [],
  "Locale": null,
  "DateCreated": "2022-03-16T22:51:25.217+00:00",
  "PasswordLastSetDate": "2022-03-16T22:51:25.26+00:00"
}

Concerns

If you don’t specify the ApiUrl or the AuthUrl, your code will be pointed at production endpoints. To me, this is a little bit backwards, and they should by default point at the sandbox. As it is, you should just run into the problem above where the client_id is invalid, but there’s a slim chance that you could be using production credentials, and then if you make a mess, you’re making a mess in prod.

And That's my two cents

I hope this has been helpful. Thanks for reading. :-)