Authorize.NET offers a very thorough SDK..
You can simply install it in your solution:
Install-Package AuthorizeNet
We need service(s) to wrap all the capabilities of the AuthorizeNet API.
For simplicity, let's say that the API exposes the following methods:
public bool Pay(TransactionModel trans);
public bool Decline(Guid id);
public bool Refund(Guid id);
We have easy access to these methods from our own solution controller methods. For example:
[HttpPost]
public bool PayAuthNet([FromBody] AuthnetTransModel model)
{
TransactionModel localTransModel = CreateLocalAuthModel(model);
var authNet = new AuthorizeNet();
return authNet.Pay(localTransModel);
}
However, the API library is pretty vast that Authorize.NET exposes:
Assuming that we want to wrap these controllers, each into its own microservice (would like feedback on this approach), Is there an easier way to wrap every one of these APIs, forcing the client to go through our wrapper service, rather than allowing them to hit Authorize.NET directly?
This is meant as an simple explanation because it is too long for a comment.
Will be using Pseudo code to demonstrate wrapping the AuthorizeNet
Using the example provided in the OP
[HttpPost]
public bool PayAuthNet([FromBody] AuthnetTransModel model)
{
TransactionModel localTransModel = CreateLocalAuthModel(model);
var authNet = new AuthorizeNet();
return authNet.Pay(localTransModel);
}
First the naming convention. Similar to how MVC finds controller based on the naming convention like how Name/Action
maps to NameController.Action
PayAuthNet --> AuthorizeNet.Pay
DeclineAuthNet --> AuthorizeNet.Decline
RefundAuthNet --> AuthorizeNet.Refund
And then using reflection the method argument type can be determined and a mapping function similar to how AutoMapper works would convert the provided model AuthnetTransModel
to the expected TransactionModel
argument for the function.
Hypothetically you can use expression trees to get away from magic strings
public class BillingConroller : ApiController {
[HttpPost]
public bool PayAuthNet([FromBody] AuthnetTransModel model) {
return authorizeNetWrapper.Execute<BillingConroller>(c => c.PayAuthNet(model));
}
}
Which internally would inspect the expression tree to extract the information needed to map and execute the matching wrapped API
From expression tree:
Method being invoked: PayAuthNet
Argument provider: AuthnetTransModel
After applying convention:
Found matching method: AuthorizeNet.Pay
Expected argument: TransactionModel
Construct command
Create instance of TransactionModel and copy properties from provided model
Invoke => authNet.Pay(localTransModel)