Creating a recurring order
To set up a recurring order with Svea Checkout, use the provided token. Please note that the token usage is capped at three orders per day in the production environment to ensure optimal performance and security. However, for testing purposes, the stage environment allows for unlimited use of the token.
Quantity, UnitPrice, DiscountPercent, DiscountAmount and VatPercent for each order row expected to be given in minor units.
HTTP status code 201 indicates that a new Checkout order was created.
HTTP status code 400 indicates that something went wrong. Please refer to Error messages in use.
Endpoint
/api/tokens/{token}/orders
Request
URI Parameters
Name | Description | Type | Additional Information |
---|---|---|---|
token | The value of token can be fetched from GetOrder , RecurringToken | Guid | The order should be created using CreateOrder , with recurring set to true |
Body Parameters
- Request Model
- Request Samples
- Code Snippets
Name | Description | Type | Additional Information |
---|---|---|---|
Currency | String | ||
ClientOrderNumber | A string that identifies the order in the merchant’s systems. The ClientOrderNumber is unique per order. Attempting to create a new order with a previously used ClientOrderNumber will result in an Error. | String | Max length: 32 |
MerchantSettings | MerchantSettings | ||
Cart | The total cost of the order rows in the cart needs to be higher than 0 (i.e. cart can not be empty). | Cart | |
PartnerKey | Provided by Svea to select partners. | Guid |
- Request Sample
- CreateSubsequentRecurringOrderRequestModel.cs
{
"currency": "SEK",
"clientOrderNumber": "1234ABCD",
"cart": {
"items": [
{
"articleNumber": "ABC80",
"name": "Computer",
"quantity": 300, // 3.00 units
"unitPrice": 500000, // 5000.00 SEK
"discountPercent": 1000, // 10.00% discount
"vatPercent": 2500, // 25.00% VAT
"unit": null, // e.g. pcs, kg...
"temporaryReference": null,
"rowNumber": 1,
"merchantData": null,
"rowType": "Row"
},
{
"articleNumber": "ABC81",
"name": "Another Computer",
"quantity": 200, // 2.00 units
"unitPrice": 400000, // 4000.00 SEK
"discountAmount": 10000, // 100.00 SEK discount
"vatPercent": 2500, // 25.00% VAT
"unit": null, // e.g. pcs, kg...
"temporaryReference": null,
"rowNumber": 2,
"merchantData": null,
"rowType": "Row"
}
]
},
"merchantSettings": {
"pushUri": "https://your.domain/push-callback/{checkout.order.uri}",
"checkoutValidationCallBackUri": "https://your.domain/validation-callback/your-identifier" //<----- Optional
}
}
public class CreateSubsequentRecurringOrderRequest
{
public string Currency { get; set; } = "SEK";
public string ClientOrderNumber { get; set; } = Guid.NewGuid().ToString().Replace("-", "");
public MerchantSettings MerchantSettings { get; set; } = new MerchantSettings();
public Cart Cart { get; set; } = new Cart();
public string? PartnetKey { get; set; }
}
- CreateRecurringOrder.cs
- SubsequentRecurringOrderMockRequest.cs
public class CreateSubsequentRecurringOrderSample
{
/// <summary>
/// When creating a subsequent order, recurringToken must be provided. It is generated when you create an order with a "recurring" flag set to true.
/// </summary>
/// <param name="recurringToken"></param>
/// <returns></returns>
public static async Task CreateSubsequentOrder(string recurringToken)
{
var services = new ServiceCollection();
services.AddHttpClient("MyApiClient", client =>
{
client.BaseAddress = new Uri("https://checkoutapistage.svea.com");
});
var serviceProvider = services.BuildServiceProvider();
var httpClientFactory = serviceProvider.GetRequiredService<IHttpClientFactory>();
var httpClient = httpClientFactory.CreateClient("MyApiClient");
var jsonString = JsonSerializer.Serialize(SubsequentRecurringOrderMockRequest.CreateSubsequentOrder());
var createOrderRequestJson = new StringContent(
jsonString,
Encoding.UTF8,
"application/json");
// Add authorization header
Authentication.CreateAuthenticationToken(out string token, out string timestamp, jsonString);
httpClient.DefaultRequestHeaders.Add("Authorization", token);
httpClient.DefaultRequestHeaders.Add("Timestamp", timestamp);
var apiUrl = $"/api/tokens/{recurringToken}/orders";
try
{
HttpResponseMessage response = await httpClient.PostAsync(apiUrl, createOrderRequestJson);
// Check if the request was successful
if (response.IsSuccessStatusCode)
{
string responseData = await response.Content.ReadAsStringAsync();
Console.WriteLine("Response: " + responseData);
}
else
{
string responseData = await response.Content?.ReadAsStringAsync();
Console.WriteLine($"Response Data: {responseData ?? "No Error Response Data"}");
Console.WriteLine("Failed to retrieve data. Status code: " + response.StatusCode);
}
}
catch (HttpRequestException ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
}
public class SubsequentRecurringOrderMockRequest
{
public static CreateSubsequentRecurringOrderRequestModel CreateSubsequentOrder() => new()
{
ClientOrderNumber = Guid.NewGuid().ToString().Replace("-", ""),
MerchantSettings = new()
{
PushUri = "https://www.google.com", //https://localhost:3000/pushUri/{checkout.order.uri}",
CheckoutValidationCallBackUri = null // Cannot be localhost. It must be an endpoint reachable from Svea's network. See Network Rules.
},
Cart = new Cart()
{
Items = new List<OrderRow>(){
new() {
Name="Article1",
Quantity=500,
UnitPrice=100,
ArticleNumber="123-456-789",
Unit="st"
},
new() {
Name="Article2",
Quantity=500,
UnitPrice=100,
ArticleNumber="123-asd-fgh",
Unit="st"
},
}
}
};
};
Response
- Response Model
- Response Sample
Name | Description | Type | Additional Information |
---|---|---|---|
OrderId | ID of the order, needed to get order in the Checkout API and Order Management | Int64 | |
ClientOrderNumber | String | ||
Status | The current status of the order | CheckoutOrderStatus | |
Cart | Order rows. | Cart | |
Currency | Currency as defined by ISO 4217 | String | |
Customer | Customer information | Customer | |
CountryCode | Defined by two-letter ISO 3166-1 alpha-2, e.g. SE, NO, FI, DK | String | |
EmailAddress | Customer's email address | String | |
PhoneNumber | Customer's phone number | String | |
ShippingAddress | Customer's shipping address. | Address | |
BillingAddress | Customer's billing address. | Address | |
PaymentType | The payment method that the customer used to finish the purchase. Only set when order status is Final
| String | |
Payment | The payment method that the customer used to finish the purchase. Only set when order status is Final | PaymentInfo | |
SveaWillBuyOrder | True = Svea will buy this invoice. False = Svea will not buy this invoice. null = Selected payment method is not Invoice. | Boolean | |
MerchantSettings | MerchantSettings | ||
CustomerReference | B2B Customer reference | String | |
PeppolId | A company's ID in the PEPPOL network, which allows the company to receive PEPPOL invoices. A PEPPOL ID can be entered when placing a B2B order using the payment method invoice. | String | |
MerchantData | Metadata visible to the store | String | Cleaned up from Checkout database after 45 days. |
Recurring | Indicates if the order is recurring order and will create a recurring token when order is finalized. Only applicable if merchant has recurring orders enabled. | Boolean / Null | If merchant utilizes shipping (nShift) recurring orders cannot be set |
RecurringToken | Recurring token to be used for subsequent recurring orders. Only available when order is finalized. Only applicable if merchant has recurring orders enabled. | Guid / Null |
{
"merchantSettings": {
"checkoutValidationCallBackUri": "https://your.domain/validation-callback/your-identifier", //<----- Optional
"pushUri": "https://your.domain/push-callback/{checkout.order.uri}"
},
"cart": {
"items": [
{
"articleNumber": "ABC80",
"name": "Computer",
"quantity": 300, // 3.00 units
"unitPrice": 500000, // 5000.00 SEK
"discountPercent": 1000, // 10.00% discount
"vatPercent": 2500, // 25.00% VAT
"unit": null, // e.g. pcs, kg...
"temporaryReference": null,
"rowNumber": 1,
"merchantData": null,
"rowType": "Row"
},
{
"articleNumber": "ABC81",
"name": "Another Computer",
"quantity": 200, // 2.00 units
"unitPrice": 400000, // 4000.00 SEK
"discountAmount": 10000, // 100.00 SEK discount
"vatPercent": 2500, // 25.00% VAT
"unit": null, // e.g. pcs, kg...
"temporaryReference": null,
"rowNumber": 2,
"merchantData": null,
"rowType": "Row"
}
]
},
"customer": {
"id": 1,
"nationalId": "121314-1234",
"countryCode": "SE",
"isCompany": false
},
"shippingAddress": {
"fullName": "John Doe",
"firstName": "John",
"lastName": "Doe",
"streetAddress": "My Street 1",
"coAddress": "",
"postalCode": "99999",
"city": "My Town",
"countryCode": "SE",
"isGeneric": false,
"addressLines": []
},
"billingAddress": {
"fullName": "John Doe",
"firstName": "John",
"lastName": "Doe",
"streetAddress": "My Street 1",
"coAddress": "",
"postalCode": "99999",
"city": "My Town",
"countryCode": "SE",
"isGeneric": false,
"addressLines": []
},
"currency": "SEK",
"countryCode": "SE",
"clientOrderNumber": "ABCDEFGHIJKLMNOP0123456789",
"orderId": 569569,
"emailAddress": "john.doe@svea.com",
"phoneNumber": "0712345678",
"paymentType": "SVEACARDPAY_PF",
"payment": {
"paymentMethodType": "Card"
},
"status": "Final",
"customerReference": null,
"merchantData": null,
"peppolId": null,
"recurring": true,
"recurringToken": "4b10836f-f9e4-4b2d-32e8-08dad38a1eda"
}
MerchantSettings
Name | Description | Type | Additional Information |
---|---|---|---|
PushUri | URI to an endpoint that expects callbacks from the Checkout whenever an order’s CheckoutOrderStatus is changed. May contain a {checkout.order.uri} placeholder which will be replaced with the Checkout order ID. Requests for this endpoint are made with HTTP Method POST. Your response's HTTP Status Code is interpreted as:
| String | Must be a valid callback URI Max length: 500 |
CheckoutValidationCallBackUri | An optional URI to a location that expects callbacks from the Checkout to validate an order’s stock status. It also allows the possibility to update the Checkout order with a different ClientOrderNumber. May contain a {checkout.order.uri} placeholder which will be replaced with the Checkout order ID.Requests for this endpoint are made with HTTP Method GET. Your response's HTTP Status Code is interpreted as:
| String | Must be a valid callback URI Max length: 5200 |
Cart
Name | Description | Type | Additional Information |
---|---|---|---|
Items | Order rows. | Collection of OrderRow | Maximum allowed number of rows per order is 1000. |
OrderRow
Name | Description | Type | Additional Information | Examples |
---|---|---|---|---|
Name | Article name. | String | Max length: 40 | |
Quantity | Quantity of the product. | Int64 | 1-7 digits Minor Units. | |
UnitPrice | Price of the product including VAT. | Int64 | 1-13 digits Can be negative. Minor Units. | |
ArticleNumber | Article number | String | Max length: 256 | |
DiscountPercent | The discount percent of the order row. Cannot be used together with DiscountAmount | Int64 | Min: 0 Max: 10000 No fractions Minor Units. | |
DiscountAmount | The total discount amount for this order row. Cannot be used together with DiscountPercent | Int64 | Min: 0 Max: Order row total Minor Units. | |
VatPercent | The VAT percentage of the current product. Valid vat percentage for that country. | Int64 | Minor Units. | |
Unit | The unit type, e.g., “st”, “pc”, “kg” etc. | String | Max length: 4 | |
TemporaryReference | Can be used when creating or updating an order. The returned rows will have their corresponding temporaryreference as they were given in the in data. It will not be stored and will not be returned in GetOrder. | String | ||
RowNumber | The row number the row will have in the Webpay system | Int32 | ||
MerchantData | Metadata visible to the store | String | Max length: 255 Cleaned up from Checkout database after 45 days. | |
RowType | Is used just to distinguish ShippingFee item from the order items. It is a string and can be one of "Row" or “ShippingFee” | String |
PaymentInfo
The final payment method for the order. Will only have a value when the order is finalized, otherwise null.
Some payment methods might include unique fields that are not available on other payment methods.
Name | Description | Type |
---|---|---|
PaymentMethodType | The final payment method type for the order:
| String |
Address
Name | Description | Type | Additional Information |
---|---|---|---|
FullName | For B2B customers this field contains the company name | String | |
FirstName | Empty for B2B customers Some address providers used by Checkout in Norway do not supply FirstName and LastName separately for B2C customers. In those cases only FullName is available. | String | |
LastName | Empty for B2B customers Some address providers used by Checkout in Norway do not supply FirstName and LastName separately for B2C customers. In those cases only FullName is available. | String | |
StreetAddress | String | ||
StreetAddress2 | May be populated on international addresses that require multiple address rows | String | |
StreetAddress3 | May be populated on international addresses that require multiple address rows | String | |
CoAddress | String | ||
PostalCode | String | ||
City | String | ||
CountryCode | String | ||
(IsGeneric) | (Deprecated) International addresses have the same structure as domestic addresses with addition of properties StreetAddress2 and StreetAddress3 Returns true if the address is a generic/international address. Generic addresses only have values in fullName and addressLines. | Boolean | |
(AddressLines) | (Deprecated) International addresses have the same structure as domestic addresses with addition of properties StreetAddress2 and StreetAddress3 This is only populated if the address is a generic/international address (IsGeneric returns true). | Collection of String |
Customer
Name | Description | Type | Additional Information |
---|---|---|---|
Id | Int64 | ||
NationalId | String | ||
CountryCode | String | ||
IsCompany | Boolean | ||
VatNumber | String | ||
IsVerified | Boolean |
CheckoutOrderStatus
CheckoutOrderStatus values indicate in which state the order session is:
Status Code | Numerical Value | Description |
---|---|---|
Cancelled | -1 | Order session becomes cancelled when time limit has expired without any purchase being finalized. When an order session is cancelled, no further actions can be made. |
Created | 0 | Checkout order session has been created and is active. When an order session is active, cart and merchantData can be changed. |
Final | 100 | Customer has seen the confirmation page which closes the checkout order session. When an order session is Final, no further actions can be made. |
Observe that none of the status codes mean that the order is ready to be delivered. To make sure that the order can be delivered, please refer to the order status of GET Order in Order Management.