Rivr 1.0.4
See the version list below for details.
dotnet add package Rivr --version 1.0.4
NuGet\Install-Package Rivr -Version 1.0.4
<PackageReference Include="Rivr" Version="1.0.4" />
paket add Rivr --version 1.0.4
#r "nuget: Rivr, 1.0.4"
// Install Rivr as a Cake Addin #addin nuget:?package=Rivr&version=1.0.4 // Install Rivr as a Cake Tool #tool nuget:?package=Rivr&version=1.0.4
Rivr .NET Client
Overview
This is an API Client library for Rivr Order API. This library enables an application to send orders for processing.
Compability
This library is built with support with .NET Standard 2.0 which provides the following compability:
.NET implementation | Version support |
---|---|
.NET and .NET Core | 2.0, 2.1, 2.2, 3.0, 3.1, 5.0, 6.0, 7.0, 8.0, 9.0 |
.NET Framework | 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1 |
If you require support for and earlier version of .NET Framework, please feel free to reach out to support@rivr.io to see what we can do.
Contribute
If you see something that can be improved, feel free to raise an issue or submit a pull request at Github.
Installation
This libary is published on Nuget. Use your favourite package manager to add it to your project.
dotnet add package Rivr
Security
The industry-standard OAuth2 security protocol is used for authorization.
Credentials
You will need a client_id
and client_secret
. Reach out to support@rivr.io and we will setup your application and provide you with the credentials you need.
Security contexts
A consumer of this library will be able to perform actions as a platform or on behalf of the managed merchants. While using this library, we have taken care of the authentication for you along with caching of access tokens.
Platform level
The platform level authentication utilizes a simplified version of OAuth2 and uses grant_type = client_credentials
, which uses client_id
and client_secret
to fetch an access_token
.
Merchant level
The merchant level authentication is a variant of OAuth2 which allows the system to act on behalf of a merchant. It is very similar to the platform level authentication, but uses our own grant_type = merchant_credentials
. With this, the client_id
and the client_secret
along with a merchant_id
are used to fetch an access_token
that includes the merchant_id
. This allows for the platform to perform actions on behalf of the merchant.
Using the client
The following section describes how to use this library.
Creating an instance of the client
var config = new Config(clientId: "clientId", clientSecret: "clientSecret");
var memoryCache = new MemoryCache(new MemoryCacheOptions());
var client = new Client(config, memoryCache);
Using Dependency Injection
await Host.CreateDefaultBuilder(args).ConfigureServices(
(context, services) =>
{
services.AddRivrClient(context.Configuration, configBuilder =>
{
/*
To run service, you need to provide your client ID and client secret.
1. Either use explicit configuration like this:
configBuilder.UseClientId("enter-client-id-here");
configBuilder.UseClientSecret("enter-client-secret-here");
configBuilder.UseTestEnvironment();
2. Or add the following to your appSettings.json:
"Rivr": {
"ClientId": "enter-client-id-here",
"ClientSecret": "enter-client-secret-here",
"Environment": "Test"
}
The explicit configuration will take precedence.
*/
});
services.AddHostedService<MyService>();
}
)
.RunConsoleAsync();
Operations
Check API health (unauthenticated)
Check that the API is online and operational using the GetHealthAsync
method.
var result = await client.GetHealthAsync();
// result.Message is "OK"
Platform operations
These operations are performed as a platform.
Check API health (using authentication)
Check that the API is online and operational using the GetHealthSecureAsync
method. This is also a way to test that the authentication works as intended.
var result = await client
.AsPlatform()
.GetHealthSecureAsync();
// result.Message is "OK"
Fetch merchants
Fetch a list of the merchants the platform is configured to act on behalf of.
var merchants = await client
.AsPlatform()
.GetMerchantsAsync();
// merchants contains an array of Merchant objects
Merchant operations
Using the merchantId's received in above mentioned operation, a number of operations can be performed on behalf of a merchant.
Check API health (using authentication)
Check that the API is online and operational using the GetHealthSecureAsync
method. This is also a way to test that the authentication for the merchant works as intended.
var merchantId = Guid.Parse("...");
var result = await client
.OnBehalfOfMerchant(merchantId)
.GetHealthSecureAsync();
// result.Message is "OK"
Fetch devices for a merchant
A merchant can be configured to have zero or more devices (checkout terminals). If a payment is to be sent to a specific device, the deviceId must be added to the order creation. Use this operation to fetch all the devices that the merchant has.
var devices = await client
.OnBehalfOfMerchant(sdkMerchantId)
.GetDevicesAsync();
// devices contains an array of Device objects
Create order (payment)
The creation of an order marks the beginning of the customer journey. The CreateOrderAsync
operation uses the HTTP PUT
VERB using order.Id
as the resource identifier. This means that the operation is idempotent. Subsequent calls using CreateOrderAsync
with the same order.Id
will result in one Order
. While this operation does support updates, the purpose of the idempotency is to enable at-least-once delivery. This is not meant to be used as a mechanism where the API keeps state for a client system. This is because the merchant may have configured its checkout to notify customers immediately which in turn means that the customer may have started to interact with the order. A completed order cannot be updated.
// Minimum order information
var order = new CreateOrderRequest
{
Id = Guid.NewGuid(),
PersonalNumber = "190001010101",
Email = "test@example.com",
Phone = "0700000000",
Reference = "123456",
OrderLines =
[
new OrderLine
{
Description = "Test Product",
Quantity = 1,
UnitPriceExclVat = 100,
VatPercentage = 0
}
]
};
// Optional order information
order.CheckoutHints =
[
new CheckoutHint
{
Type = CheckoutHintType.Device,
Value = "deviceId"
}
];
order.Metadata = new Dictionary<string, string>
{
{ "key1", "value1" },
{ "key2", "value2" }
};
order.CallbackUrl = "https://example.com/callback";
var merchantId = Guid.Parse("...");
var result = await client
.OnBehalfOfMerchant(merchantId)
.CreateOrderAsync(order);
// result contains an instance of an Order object
Fetch an order
Using the order.Id
, the order can be retrieved.
var merchantId = Guid.Parse("...");
var result = await client
.OnBehalfOfMerchant(merchantId)
.GetOrderAsync(order.Id);
// result contains an instance of an Order object
Refund or Cancel an order
And order can be either refunded or cancelled depending on the current status. If the status is OrderStatus.Completed
, the order will be refunded. If the status is OrderStatus.Created
, the order will be cancelled. The calling system does not need to know the current status of the order.
Note: There are certain payment methods that do not support refunds (some instalment products).
var merchantId = Guid.Parse("...");
await client
.OnBehalfOfMerchant(merchantId)
.RefundAsync(order.Id);
Callbacks
The integration is based on the calling system being able to receive callbacks (webhooks). The callback contains the orderId and the OrderStatus
describing the event that occurred. Depending on the event, there may be more information provided. The callback is delivered to the callbackUrl
that is set when creating the order.
Example of a callback body:
{
"id": "84c3c4ad-63d8-4d49-a4ff-ed57bbd40a39",
"type": "Order",
"status": "Created",
"data": {
"createdDate": "2024-08-19 14:58:21"
}
}
If the system is unable to receive callbacks, the GetOrderAsync
operation can be used periodically to check the status of an order.
Callback details
Callbacks from the Rivr systems are delivered using a HTTP POST to the URL supplied in the initial creation of the object.
If the request is receiving a response having HTTP Status Code in the range 200-299 it will be considered successful and no more attempts will be made.
However, if the callback isn't successful, a retry will be scheduled. A maximum of seven retries will be performed according to this schema:
Iteration | Delay |
---|---|
1 | 1 minute |
2 | 5 minutes |
3 | 30 minutes |
4 | 60 minutes |
5 | 4 hours |
6 | 12 hours |
7 | 24 hours |
If the last iteration is not successful, no more attempts will be made.
Note: If the Callback URL is empty or malformatted there will be no attempts at all.
Order
Here follows a detailed overview of the callbacks related to the Order entity.
Created
Immediately after an order is created a callback is issued.
{
"id": "84c3c4ad-63d8-4d49-a4ff-ed57bbd40a39",
"type": "Order",
"status": "Created",
"data": {
"CreatedDate": "2024-04-24T16:45:30.582Z"
}
}
Pending
If an order is tranferred to an invoice with recourse, the order state is set to pending meaning that there has been an action on it but it is not completed yet. The order will be completed when the invoice is paid in full.
{
"id": "84c3c4ad-63d8-4d49-a4ff-ed57bbd40a39",
"type": "Order",
"status": "Pending",
"data": {
"CreatedDate": "2024-04-24T16:45:30.582Z"
}
}
Completed
A order is considered Completed
when it has been paid. An Order can be paid with a different payment methods. The different variants of callbacks are listed here.
Card
{
"id": "84c3c4ad-63d8-4d49-a4ff-ed57bbd40a39",
"type": "Order",
"status": "Completed",
"data": {
"CreatedDate": "2024-04-24T16:45:30.582Z",
"CompletedDate": "2024-04-24T16:45:52.54Z",
"PaymentMethod": "Card"
}
}
Apple Pay / Google Pay
{
"id": "84c3c4ad-63d8-4d49-a4ff-ed57bbd40a39",
"type": "Order",
"status": "Completed",
"data": {
"CreatedDate": "2024-04-24T16:45:30.582Z",
"CompletedDate": "2024-04-24T16:45:52.54Z",
"PaymentMethod": "DigitalWallet"
}
}
Swish
{
"id": "84c3c4ad-63d8-4d49-a4ff-ed57bbd40a39",
"type": "Order",
"status": "Completed",
"data": {
"CreatedDate": "2024-04-24T16:45:30.582Z",
"CompletedDate": "2024-04-24T16:45:52.54Z",
"PaymentMethod": "Swish"
}
}
Invoice
{
"id": "84c3c4ad-63d8-4d49-a4ff-ed57bbd40a39",
"type": "Order",
"status": "Completed",
"data": {
"CreatedDate": "2024-04-24T16:45:30.582Z",
"CompletedDate": "2024-04-24T16:45:52.54Z",
"PaymentMethod": "Invoice"
}
}
Instalment
Instalment comes in three flavours, Default, Full KYC and Interest Free.
{
"id": "84c3c4ad-63d8-4d49-a4ff-ed57bbd40a39",
"type": "Order",
"status": "Completed",
"data": {
"CreatedDate": "2024-04-24T16:45:30.582Z",
"CompletedDate": "2024-04-24T16:45:52.54Z",
"PaymentMethod": "InstalmentDefault"
}
}
{
"id": "84c3c4ad-63d8-4d49-a4ff-ed57bbd40a39",
"type": "Order",
"status": "Completed",
"data": {
"CreatedDate": "2024-04-24T16:45:30.582Z",
"CompletedDate": "2024-04-24T16:45:52.54Z",
"PaymentMethod": "InstalmentFullKyc"
}
}
{
"id": "84c3c4ad-63d8-4d49-a4ff-ed57bbd40a39",
"type": "Order",
"status": "Completed",
"data": {
"CreatedDate": "2024-04-24T16:45:30.582Z",
"CompletedDate": "2024-04-24T16:45:52.54Z",
"PaymentMethod": "InstalmentInterestFree"
}
}
Cancelled
Orders can be cancelled.
{
"id": "84c3c4ad-63d8-4d49-a4ff-ed57bbd40a39",
"type": "Order",
"status": "Cancelled",
"data": {
"CreatedDate": "2024-04-24T16:45:30.582Z",
"CancelledDate": "2024-04-24T16:45:52.54Z",
"Reason": "Timeout | UserCancelled | MerchantCancelled"
}
}
Refunded
An order can be refunded and when successful this callback is sent.
{
"id": "84c3c4ad-63d8-4d49-a4ff-ed57bbd40a39",
"type": "Order",
"status": "Refunded",
"data": {
"CreatedDate": "2024-04-24T16:45:30.582Z",
"RefundedDate": "2024-04-24T16:45:52.54Z"
}
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Extensions.Caching.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Caching.Memory (>= 8.0.0)
- Microsoft.Extensions.Configuration (>= 8.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 8.0.2)
- Microsoft.Extensions.Http (>= 8.0.0)
- System.Text.Json (>= 8.0.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.