Payroc 0.0.3933

dotnet add package Payroc --version 0.0.3933
                    
NuGet\Install-Package Payroc -Version 0.0.3933
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Payroc" Version="0.0.3933" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Payroc" Version="0.0.3933" />
                    
Directory.Packages.props
<PackageReference Include="Payroc" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Payroc --version 0.0.3933
                    
#r "nuget: Payroc, 0.0.3933"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Payroc@0.0.3933
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Payroc&version=0.0.3933
                    
Install as a Cake Addin
#tool nuget:?package=Payroc&version=0.0.3933
                    
Install as a Cake Tool

Payroc API .Net SDK

The Payroc API .Net SDK provides convenient access to the Payroc API from .Net.

Contents

Installation

dotnet add package Payroc

Usage

API Key

You need to provide your API Key to the PayrocClient constructor. In this example we read it from an environment variable named PAYROC_API_KEY. In your own code you should consider security and compliance best practices, likely retrieving this value from a secure vault on demand.

PayrocClient

Instantiate and use the client with the following:

using Payroc;

var apiKey = Environment.GetEnvironmentVariable("PAYROC_API_KEY") ?? throw new Exception("Payroc API Key not found");
var client = new PayrocClient(apiKey);

Then you can access the various API endpoints through the client object. For example, to create a payment:

using Payroc.CardPayments.Payments;

await client.CardPayments.Payments.CreateAsync(
    new PaymentRequest
    {
        IdempotencyKey = "8e03978e-40d5-43e8-bc93-6894a57f9324",
        Channel = PaymentRequestChannel.Web,
        ProcessingTerminalId = "1234001",
        Operator = "Postman",
        Order = new PaymentOrderRequest
        {
            OrderId = "OrderRef6543",
            Description = "Large Pepperoni Pizza",
            Amount = 4999,
            Currency = Currency.Usd,
        },
        Customer = new Customer
        {
            FirstName = "Sarah",
            LastName = "Hopper",
            BillingAddress = new Address
            {
                Address1 = "1 Example Ave.",
                Address2 = "Example Address Line 2",
                Address3 = "Example Address Line 3",
                City = "Chicago",
                State = "Illinois",
                Country = "US",
                PostalCode = "60056",
            },
            ShippingAddress = new Shipping
            {
                RecipientName = "Sarah Hopper",
                Address = new Address
                {
                    Address1 = "1 Example Ave.",
                    Address2 = "Example Address Line 2",
                    Address3 = "Example Address Line 3",
                    City = "Chicago",
                    State = "Illinois",
                    Country = "US",
                    PostalCode = "60056",
                },
            },
        },
        PaymentMethod = new PaymentRequestPaymentMethod(
            new PaymentRequestPaymentMethod.Card(
                new CardPayload
                {
                    CardDetails = new CardPayloadCardDetails(
                        new CardPayloadCardDetails.Raw(
                            new RawCardDetails
                            {
                                Device = new Device
                                {
                                    Model = DeviceModel.BbposChp,
                                    SerialNumber = "PAX123456789",
                                },
                                RawData =
                                    "A1B2C3D4E5F67890ABCD1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF",
                            }
                        )
                    ),
                }
            )
        ),
        CustomFields = new List<CustomField>()
        {
            new CustomField { Name = "yourCustomField", Value = "abc123" },
        },
    }
);

Advanced Usage with Custom Environment

If you wish to use the SDK against a custom URL, such as a mock API server, you can provide a custom PayrocEnvironment to the PayrocClient constructor:

var mockEnvironment = new PayrocEnvironment
{
    Api = "http://localhost:3000",
    Identity = "http://localhost:3001"
};

var client = new PayrocClient(
    apiKey,
    new ClientOptions
    {
        Environment = mockEnvironment
    }
);

Exception Handling

When the API returns a non-success status code (4xx or 5xx response), a subclass of the following error will be thrown.

using Payroc;

try
{
    var response = await client.CardPayments.Payments.CreateAsync(...);
}
catch (PayrocApiException e)
{
    System.Console.WriteLine(e.Body);
    System.Console.WriteLine(e.StatusCode);
}

Here are the specific exceptions:

  • BadRequestError
  • ConflictError
  • ContentTooLargeError
  • ForbiddenError
  • InternalServerError
  • NotAcceptableError
  • NotFoundError
  • UnauthorizedError
  • UnsupportedMediaTypeError

Catching a specific exception will allow reading the specific data structure, and easier reading of messages. For example:

using Payroc;

try
{
    var response = await client.CardPayments.Payments.CreateAsync(...);
}
catch (BadRequestError e)
{
    // Specific handling of a specific error, `BadRequestError`, allows reading more detail
    // Details has the overall message, e.g. "Validation error..."
    System.Console.WriteLine(e.Body.Details);
    
    foreach(var error in e.Body.Errors)    
    {
        // These individual messages will list details, e.g. individual validation errors
        System.Console.WriteLine(error.Message);
    }

    System.Console.WriteLine(e.StatusCode);
}
catch (PayrocApiException e)
{
    // Fallback to generic exception
    // Note there's no `.Details` on `e.Body`
    System.Console.WriteLine(e.Body);
    System.Console.WriteLine(e.StatusCode);
}

Logging

Be careful when configuring your logging not to log the headers of outbound HTTP requests, lest you leak an API key or access token.

Pagination

List endpoints are paginated. The SDK provides an IAsyncEnumerable so that you can simply loop over the items. Note the await before the foreach:

using Payroc.CardPayments.Payments;
using Payroc;

var pager = await client.CardPayments.Payments.ListAsync(new ListPaymentsRequest { ProcessingTerminalId = "1234001"});

await foreach (var item in pager)
{
    // do something with item
}

Pagination Gotcha

Beware of iterating the items on a single page and thinking that they are all there are. In the following example, there are only 10 items of the available 100, because this is iterating the items on a single page:

var pager = await client.CardPayments.Payments.ListAsync(new ListPaymentsRequest());

var ids = new List<int>();

foreach (var payment in pager.CurrentPage.Items)
{
    var id = payment.PaymentId;
    ids.Add(int.Parse(id[^2..]));
}

This might be helpful when you only want to process the first few results, but to iterate all items, the await foreach approach is recommended.

Request Parameters

Sometimes you need to filter results, for example, retrieving results from a given date. Raw API calls might use query parameters. The SDK equivalent pattern is setting the values in the request object itself.

Examples of setting different query parameters via the request object:

    new ListPaymentsRequest
    {
        ProcessingTerminalId = "1234001",
        DateFrom = new DateTime(2024, 07, 01, 15, 30, 00, 000)
    }
    new ListPaymentsRequest
    {
        ProcessingTerminalId = "1234001",
        DateTo = new DateTime(2024, 07, 03, 15, 30, 00, 000)
    }
    new ListPaymentsRequest
    {
        ProcessingTerminalId = "1234001",
        After = "8516"
    }
    new ListPaymentsRequest
    {
        ProcessingTerminalId = "1234001",
        Before = "2571"
    }

Inspect the code definition of your particular ...Request object in your IDE to see what properties can be used for filtering.

Polymorphic Types

Our API makes frequent use of polymorphic data structures. This is when a value might be one of multiple types, and the type is determined at runtime. For example, a contact method can be one of several methods, such as Email or Fax. The SDK provides a way to handle this using the OneOf library, as well as some helper methods.

Creating Polymorphic Data

Normally, when something has a single type, we simply use the constructor. We can also use var to avoid specifying the receiving type. For example:

var address = new Address()
{
    // ...
};

Since C# 9 / .Net 5, we can use "target-typed expressions" to simplify it as just new(), omitting the name of the Address type, albeit specifying Address at the beginning to specify the type:

Address address = new()
{
    // ...
};

However, when dealing with polymorphic types, we need to specify which type we are using, so can no longer use "target-typed expressions". We provide a helper factory method on each polymorphic type to help achieve this cleanly.

The ContactMethod type has a method for each possible polymorphic variant, such as ContactMethod.Email(), ContactMethod.Fax() etc.

This can look as simple as:

var a = new ContactMethod.Email(new() { Value = "jane.doe@example.com" });
var b = new ContactMethod.Fax(new() { Value = "2025550110" });

Note the use of both var and the new() expression to create the inner object, which is a ContactMethodEmail in this case. This is a common pattern in the SDK to keep the code clean and readable.

So to summarize, when you're looking to create a polymorpohic instance, you should start by locating the factory method for the type you're after, and then in that constructor, can use the "target-typed expression" to automatically select the correct inner variant type for you. This pattern will keep your code clean from unnecessary boilerplate / noise.

Handling Polymorphic Data

Let's look at an example of how we can interact with polymorphic types in SDK responses:

using Payroc.Boarding.Owners;

var owners = await client.Boarding.Owners.RetrieveAsync(new RetrieveOwnersRequest { OwnerId = 4564 });

foreach (var contactMethod in owners.ContactMethods)
{
    // How to read common properties regardless of type
    Console.WriteLine($"Contact Method: {contactMethod.Type} - {contactMethod.Value}");

    // How to check if the contact method is a particular type,
    // and then extract the specific, inner type
    if (contactMethod.IsEmail)
    {
        var email = contactMethod.AsEmail();

        // If email had type-specific properties, you could access them on this instance,
        // e.g. email.SomeTypeSpecificProperty
    }

    // How to use the `Match ()` function to handle different types:
    var formattedValue = contactMethod.Match(
        onEmail: email => $"Email: {email.Value}",
        onPhone: phone => $"Phone: {phone.Value}",
        onMobile: mobile => $"Mobile: {mobile.Value}",
        onFax: fax => $"Fax: {fax.Value}",
        onUnknown_: (typeName, value) => "Unknown contact method type"
    );

    // How to use `Visit()` to apply different actions based on different types:
    contactMethod.Visit(
        onEmail: email => someService.SendWelcomeEmail(email.Value),
        onPhone: phone => { },
        onMobile: mobile => { },
        onFax: fax => someService.SendWelcomeFax(fax.Value),
        onUnknown_: (typeName, value) => { }
    );

Advanced

Timeouts

The SDK defaults to a 30 second timeout. You can configure this with a timeout option at the client or request level.

// Client level
var client = new PayrocClient(
    apiKey,
    new ClientOptions
    {
        Timeout = TimeSpan.FromSeconds(10)
    }
);

// Request level
var response = await client.CardPayments.Payments.CreateAsync(
    ...,
    new RequestOptions
    {
        Timeout = TimeSpan.FromSeconds(3) // Override timeout to 3s
    }
);

Error Telemetry

The SDK automatically reports anonymous errors to help improve the SDK quality. This is enabled by default but can be disabled.

Opt-Out

To disable error telemetry:

var client = new PayrocClient(
    apiKey,
    new ClientOptions
    {
        Telemetry = false
    }
);
Privacy

All sensitive data (API keys, tokens, passwords, PII) is automatically scrubbed before transmission.

Contributing

While we value open-source contributions to this SDK, this library is generated programmatically. Additions made directly to this library would have to be moved over to our generation code, otherwise they would be overwritten upon the next generated release. Feel free to open a PR as a proof of concept, but know that we will not be able to merge it as-is. We suggest opening an issue first to discuss with us!

On the other hand, contributions to the README are always very welcome!

For details on setting up your development environment, running tests, and code quality standards, please see CONTRIBUTING.md.

References

The Payroc API SDK is generated via Fern.

fern shield

Product 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 is compatible.  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.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.3933 131 2/23/2026