Real-time Authorizations

The Sudo API allows you to set up an asynchronous webhook to approve or decline transactions in real-time.

Your webhook endpoint can be set up by creating a funding source and setting that funding source while creating a new card or updating an existing one. Sudo creates and sends you an authorization.request event to approve or decline the authorization.

Authorization Requests

Your webhook must approve or decline each authorization request sent by responding with the appropriate response body. If Sudo does not receive a response from you within 4 seconds, the Authorization is automatically approved or declined based on your timeout settings in the card funding source.

📘

Insufficient Balance

If your main wallet balance does not have enough funds for the incoming authorization, it is automatically declined and you will not receive an event on your webhook.

let bodyParser      = require("body-parser");
let cors            = require("cors");
let express         = require("express");
let app             = express();

app.use(bodyParser());
app.use(cors());

app.get('/', (req, res) => {
    return res.json({
        foo: "Bar!"
    });
});

app.post('/sudo/jitgateway', (req, res) => {
    if(req.body.type === "card.balance") {
        res.status(200);
        res.json({
            statusCode: 200,
            responseCode: "00",
            data: {
                balance: 40000
            }
        });
    }else if(req.body.type === "authorization.request") {
        res.status(200);
        res.json({
            statusCode: 200,
            responseCode: "00",
            data: {
                metadata: {
                    foo: "bar"
                }
            }
        });
    }else {
        res.status(403);
        res.json({
            statusCode: 403,
            responseCode: "96",
            message: "Error"
        });
    }
});

app.listen(process.env.PORT || 3000, () => {
    console.log("Server's Up!");
});

In the example above, we set up an express server and exposed an endpoint /sudo/jitgateway to accept POST requests. This is listening to two event card.balance and authorization.request. Responding to the webhook request with a status 200 and a JSON body with statusCode 200 approves the authorization request.

{
    "statusCode":200,
    "responseCode":"00",
    "data":{
        "metadata":{
            "foo":"bar"
        }
    }
}

Optionally, you can add some metadata to the authorization request to be passed to the transaction eventually approved or an ISO 8583 responseCode to be returned for the authorization.

{
    "statusCode":400,
    "responseCode":"51"
}

The example response body above rejects a transaction with a response code 51 indicating Insufficient Balance.

Balance Requests

When a balance request is sent to your webhook, take a look at the user and account details then respond with the appropriate body indicating the user's spendable balance.

{
    "business":"61cc42a046996fb949322a3e",
    "data":{
        "object":{
            "_id":"61ce491d9400b25b439ae426",
            "business":"61cc42a046996fb949322a3e",
            "customer":{
                "_id":"61ccdc228ce8d1fe6dceacf9",
                "business":"61cc42a046996fb949322a3e",
                "type":"individual",
                "name":"John Doe",
                "status":"active",
                "individual":{
                    "firstName":"John",
                    "lastName":"Doe",
                    "_id":"61ccdc228ce8d1fe6dceacfa"
                },
                "billingAddress":{
                    "line1":"4 Barnawa Close",
                    "line2":"Off Challawa Crescent",
                    "city":"Barnawa",
                    "state":"Kaduna",
                    "country":"Nigeria",
                    "postalCode":"800243",
                    "_id":"61ccdc228ce8d1fe6dceacfb"
                },
                "isDeleted":false,
                "createdAt":"2021-12-29T22:07:30.301Z",
                "updatedAt":"2021-12-29T22:07:30.301Z",
                "__v":0
            },
            "account":{
                "_id":"61ce491d9400b25b439ae424",
                "business":"61cc42a046996fb949322a3e",
                "type":"wallet",
                "currency":"NGN",
                "accountName":"SUDO / JOHN DOE",
                "bankCode":"999240",
                "accountType":"Current",
                "accountNumber":"8016065912",
                "currentBalance":0,
                "availableBalance":0,
                "provider":"SafeHaven",
                "providerReference":"61ce491d3153ed001e8425e2",
                "referenceCode":"subacc_1640909083619",
                "isDefault":true,
                "isDeleted":false,
                "createdAt":"2021-12-31T00:04:45.657Z",
                "updatedAt":"2021-12-31T00:04:45.657Z",
                "__v":0
            },
            "fundingSource":{
                "_id":"61ccdc118ce8d1fe6dceacf0",
                "business":"61cc42a046996fb949322a3e",
                "type":"gateway",
                "status":"active",
                "jitGateway":{
                    "url":"https://AfraidRoughRedundancy.aminubakori.repl.co/sudo/jitgateway",
                    "authorizationHeader":"Bearer ACME_TOKEN",
                    "authorizeByDefault":false,
                    "_id":"61ccdc118ce8d1fe6dceacf1"
                },
                "isDefault":false,
                "isDeleted":false,
                "createdAt":"2021-12-29T22:07:13.392Z",
                "updatedAt":"2021-12-29T22:07:13.392Z",
                "__v":0
            },
            "type":"physical",
            "brand":"Verve",
            "currency":"NGN",
            "maskedPan":"444444******4430",
            "expiryMonth":"01",
            "expiryYear":"2025",
            "status":"active",
            "spendingControls":{
                "channels":{
                    "atm":true,
                    "pos":true,
                    "web":true,
                    "mobile":true,
                    "_id":"61ce491d9400b25b439ae428"
                },
                "allowedCategories":[
                    
                ],
                "blockedCategories":[
                    
                ],
                "spendingLimits":[
                    {
                        "amount":1000,
                        "interval":"daily",
                        "categories":[
                            
                        ],
                        "_id":"61ce491d9400b25b439ae429"
                    }
                ],
                "_id":"61ce491d9400b25b439ae427"
            },
            "isDeleted":false,
            "createdAt":"2021-12-31T00:04:45.840Z",
            "updatedAt":"2021-12-31T00:04:45.840Z",
            "__v":0
        },
        "_id":"61d8f3cec46018873905a908"
    },
    "type":"card.balance",
    "pendingWebhook":false,
    "webhookArchived":false,
    "createdAt":1641608142,
    "_id":"61d8f3cec46018873905a907"
}

Authorization Requests

When an authorization request is sent to your webhook, the amount requested is stored in pendingRequest object.

{
    "environment":"development",
    "business":"61cc42a046996fb949322a3e",
    "data":{
        "object":{
            "_id":"61d8f42bc46018873905a955",
            "business":"61cc42a046996fb949322a3e",
            "customer":{
                "_id":"61ccdc228ce8d1fe6dceacf9",
                "business":"61cc42a046996fb949322a3e",
                "type":"individual",
                "name":"John Doe",
                "status":"active",
                "individual":{
                    "firstName":"John",
                    "lastName":"Doe",
                    "_id":"61ccdc228ce8d1fe6dceacfa"
                },
                "billingAddress":{
                    "line1":"4 Barnawa Close",
                    "line2":"Off Challawa Crescent",
                    "city":"Barnawa",
                    "state":"Kaduna",
                    "country":"Nigeria",
                    "postalCode":"800243",
                    "_id":"61ccdc228ce8d1fe6dceacfb"
                },
                "isDeleted":false,
                "createdAt":"2021-12-29T22:07:30.301Z",
                "updatedAt":"2021-12-29T22:07:30.301Z",
                "__v":0
            },
            "account":{
                "_id":"61ce491d9400b25b439ae424",
                "business":"61cc42a046996fb949322a3e",
                "type":"wallet",
                "currency":"NGN",
                "accountName":"SUDO / JOHN DOE",
                "bankCode":"999240",
                "accountType":"Current",
                "accountNumber":"8016065912",
                "currentBalance":0,
                "availableBalance":0,
                "provider":"SafeHaven",
                "providerReference":"61ce491d3153ed001e8425e2",
                "referenceCode":"subacc_1640909083619",
                "isDefault":true,
                "isDeleted":false,
                "createdAt":"2021-12-31T00:04:45.657Z",
                "updatedAt":"2021-12-31T00:04:45.657Z",
                "__v":0
            },
            "card":{
                "_id":"61ce491d9400b25b439ae426",
                "business":"61cc42a046996fb949322a3e",
                "customer":"61ccdc228ce8d1fe6dceacf9",
                "account":"61ce491d9400b25b439ae424",
                "fundingSource":{
                    "_id":"61ccdc118ce8d1fe6dceacf0",
                    "business":"61cc42a046996fb949322a3e",
                    "type":"gateway",
                    "status":"active",
                    "jitGateway":{
                        "url":"https://AfraidRoughRedundancy.aminubakori.repl.co/sudo/jitgateway",
                        "authorizationHeader":"Bearer ACME_TOKEN",
                        "authorizeByDefault":false,
                        "_id":"61ccdc118ce8d1fe6dceacf1"
                    },
                    "isDefault":false,
                    "isDeleted":false,
                    "createdAt":"2021-12-29T22:07:13.392Z",
                    "updatedAt":"2021-12-29T22:07:13.392Z",
                    "__v":0
                },
                "type":"physical",
                "brand":"Verve",
                "currency":"NGN",
                "maskedPan":"444444******4430",
                "expiryMonth":"01",
                "expiryYear":"2025",
                "status":"active",
                "spendingControls":{
                    "channels":{
                        "atm":true,
                        "pos":true,
                        "web":true,
                        "mobile":true,
                        "_id":"61ce491d9400b25b439ae428"
                    },
                    "allowedCategories":[
                        
                    ],
                    "blockedCategories":[
                        
                    ],
                    "spendingLimits":[
                        {
                            "amount":1000,
                            "interval":"daily",
                            "categories":[
                                
                            ],
                            "_id":"61ce491d9400b25b439ae429"
                        }
                    ],
                    "_id":"61ce491d9400b25b439ae427"
                },
                "isDeleted":false,
                "createdAt":"2021-12-31T00:04:45.840Z",
                "updatedAt":"2021-12-31T00:04:45.840Z",
                "__v":0
            },
            "amount":0,
            "fee":5,
            "vat":0.375,
            "approved":false,
            "currency":"NGN",
            "status":"pending",
            "authorizationMethod":"online",
            "balanceTransactions":[
                
            ],
            "merchantAmount":20,
            "merchantCurrency":"NGN",
            "merchant":{
                "category":"6010",
                "name":"SUDO SIMULATOR",
                "merchantId":"SUDOSIMULATOR01",
                "city":"JAHI",
                "state":"ABUJA",
                "country":"NG",
                "postalCode":"100001",
                "_id":"61d8f42bc46018873905a956"
            },
            "terminal":{
                "rrn":"126769857082",
                "stan":"192208",
                "terminalId":"3SUDOSIM",
                "terminalOperatingEnvironment":"on_premise",
                "terminalAttendance":"unattended",
                "terminalType":"ecommerce",
                "panEntryMode":"keyed_in",
                "pinEntryMode":"keyed_in",
                "cardHolderPresence":true,
                "cardPresence":true,
                "_id":"61d8f42bc46018873905a957"
            },
            "transactionMetadata":{
                "channel":"web",
                "type":"purchase",
                "reference":"0123456783126769857082",
                "_id":"61d8f42bc46018873905a958"
            },
            "pendingRequest":{
                "amount":25.375,
                "currency":"NGN",
                "merchantAmount":20,
                "merchantCurrency":"NGN",
                "_id":"61d8f42bc46018873905a959"
            },
            "requestHistory":[
                
            ],
            "verification":{
                "billingAddressLine1":"not_provided",
                "billingAddressPostalCode":"not_provided",
                "cvv":"match",
                "expiry":"match",
                "pin":"match",
                "threeDSecure":"not_provided",
                "safeToken":"not_provided",
                "authentication":"pin",
                "_id":"61d8f42bc46018873905a95a"
            },
            "isDeleted":false,
            "createdAt":"2022-01-08T02:17:15.075Z",
            "updatedAt":"2022-01-08T02:17:15.075Z",
            "feeDetails":[
                {
                    "contract":"61a18b8a4ddab599d20344a7",
                    "currency":"NGN",
                    "amount":5,
                    "description":"Verve Card Authorization Fee",
                    "_id":"61d8f42bc46018873905a95b"
                }
            ],
            "__v":0
        },
        "_id":"61d8f42bc46018873905a96f",
        "changes":" {\n-  amount: 0\n+  amount: 25.375\n-  approved: false\n+  approved: true\n-  status: \"pending\"\n+  status: \"approved\"\n-  pendingRequest: {\n-    amount: 25.375\n-    currency: \"NGN\"\n-    merchantAmount: 20\n-    merchantCurrency: \"NGN\"\n-    _id: \"61d8f42bc46018873905a959\"\n-  }\n+  pendingRequest: null\n   requestHistory: [\n+    {\n+      amount: 25.375\n+      currency: \"NGN\"\n+      approved: true\n+      merchantAmount: 20\n+      merchantCurrency: \"NGN\"\n+      reason: \"webhook_approved\"\n+      createdAt: \"2022-01-08T02:17:15.075Z\"\n+      _id: \"61d8f42cc46018873905a979\"\n+    }\n   ]\n }\n"
    },
    "type":"authorization.request",
    "pendingWebhook":false,
    "webhookArchived":false,
    "createdAt":1641608235,
    "_id":"61d8f42bc46018873905a96e"
}

The top-level amount in the request is set to 0 and approved is false. Once you respond to the request, the top-level amount reflects the total amount approved or declined, the approved field is updated, and pendingRequest is set to null.