Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

INTERFACE SPECIFICATION (APP → ONEPIPE)

Info

For details on encryption using the Triple DES Algorithm, read this.

A note on the secure element

  • Once it's card, it should be: TripleDES.encrypt("{card.Pan};{card.Cvv};{card.Expdate};{card.Pin}",secretKey)

  • Once it's bank.account , it shd be: TripleDES.encrypt("{accountNumber};{bankCBNCode}",secretKey)

  • Once it's wallet , it shd be: TripleDES.encrypt("{walletNumber};{providerCode}",secretKey)

  • Once it's airtime , it shd be: TripleDES.encrypt("{phoneNumber};{telcoCode}",secretKey)

  • Once it's voucher , it shd be: TripleDES.encrypt("{voucherCode};{providerCode}",secretKey)

  • Once it's bvn , it shd be: TripleDES.encrypt("{bvn}",secretKey)

Note

NOTE: While it’s such that some providers will need a PIN for their auth Type, others will likely not. But the interfaces are standardized not to request this value (except in the case of cards). If a provider needs it, they should respond with PendingValidation and request for the PIN.

A typical /transact request

The actual API call to process a transaction

...

languagejson

...

Here’s what a standard OnePipe call will look like:

Code Block
{
  "request_ref":"{{request_ref}}", //a unique ref
  "request_type":"transfer_funds", //what service are you trying to execute
  "auth": {...}, //security details and what provider to forward the request to
  "transaction": {...} //details required to complete every call. Varies per service type
}

Supported operations on OnePipe

Calls to OnePipe APIs all go {{baseUrl}}/v2/transact/{{operation}}

  1. Transact - The main call for the API service being requested: {{baseUrl}}/v2/transact/

  2. Validate - Some services require a follow up call to finalise with an OTP or validation code. : {{baseUrl}}/v2/transact/validate

  3. Options - Some services allow (or require) a preliminary options call to get some parameters to use in the main call: {{baseUrl}}/v2/transact/options

  4. Query - All services support a way to query for status : {{baseUrl}}/v2/transact/query

  5. Fulfil - Some services and providers support the ability to request for a partially completed transaction to be retried {{baseUrl}}/v2/transact/fulfil

  6. Reverse - Some providers support the ability to rollback a transaction {{baseUrl}}/v2/transact/reverse

Interface specification (App → OnePipe)

Info

All calls to OnePipe support for authorization details to be passed in where required in the auth.secure element.

A note on the secure element

  • When auth.type is ‘card’, it should be: TripleDES.encrypt("{card.Pan};{card.Cvv};{card.Expdate};{card.Pin}",secretKey)

  • When auth.type is ‘bank.account’ , it shd be: TripleDES.encrypt("{accountNumber};{bankCBNCode}",secretKey)

  • When auth.type is ‘wallet’ , it shd be: TripleDES.encrypt("{walletNumber};{providerCode}",secretKey)

  • When auth.type is ‘airtime’ , it shd be: TripleDES.encrypt("{phoneNumber};{telcoCode}",secretKey)

  • When auth.type is ‘voucher’ , it shd be: TripleDES.encrypt("{voucherCode};{providerCode}",secretKey)

  • When auth.type is ‘bvn’, it shd be: TripleDES.encrypt("{bvn}",secretKey)

  • When auth.type is ‘basic’ , it shd be: TripleDES.encrypt("{userName};{password}",secretKey)

  • When auth.type is 'custom' (masterpass specifically) , it shd be: TripleDES.encrypt("{user_id};{card_id};{pin}",secretKey)

  • When auth.type is ‘custom’ (anything else) , it shd be: TripleDES.encrypt("{ref}",secretKey)

For details on encryption using the Triple DES Algorithm, read this.

NOTE: While it’s such that some providers will need a PIN for their auth Type, others will likely not. But the interfaces are standardized not to request this value (except in the case of cards). If a provider needs it, they should respond with PendingValidation and request for the PIN.

A typical /transact request

The actual API call to process a transaction

Code Block
languagejson
{
  "request_ref":"{{request_ref}}", 
  "request_type":"transfer_funds",
  "request_mode":"transact | validate | query | reverse",
  "auth": {
    "type": "bank.account | card | wallet", 
    "secure": "{{encrypted(bank account details | card details | wallet)}}",
    "auth_provider": "Beeceptor",
    "route_mode": null
  },
  "transaction": {
    "mock_mode": "live", 
    "transaction_ref": "{{transaction_ref}}", 
    "transaction_desc": "A random transaction", 
    "transaction_ref_parent": null, 
    "amount": 1000,
    "customer":{
    	"customer_ref": "{{customer_id}}",
    	"firstname": "Uju",
        "surname": "Usmanu",
    	"email": "ujuusmanu@gmail.com",
    	"mobile_no": "234802343132"
    },
    "meta":{
    	"a_key":"a_meta_value_1",
    	"another_key":"a_meta_value_2"
    },
    "details": {
    	"a_key":"a_value",
        "a_key":"a_value"
    }
  }
}

A typical completion response (Successful or Failed)

If all checks out.

Code Block
languagejson
{
    "status": "Successful",
    "message": "Transaction processed successfully",
    "data": {
        "provider_response_code": "00",
        "provider": "Beeceptor",
        "surnameerrors": "Usmanu"null,
     	   "emailerror": "ujuusmanu@gmail.com",null,
        	"mobileprovider_noresponse": "234802343132"{
       },     "metareference":{ "000022200225154318222333334432",
            	"adestination_institution_keycode":"a_meta_value_1 "000016",
    	"another_key":"a_meta_value_2"
    },        "beneficiary_account_name": "JOHN DOE JAMES",
       "details": {     	"abeneficiary_account_keynumber": "a_value3056433222",
         "a_key   "beneficiary_kyc_level": "a_value3",
    }   } }

A typical completion response (Successful or Failed)

If all checks out.

Code Block
languagejson
{
    "statusoriginator_account_name": "SuccessfulJames Jane",
            "messageoriginator_account_number": "Transaction processed successfully0001131256",
  
 "data":  {         "provideroriginator_responsekyc_codelevel": "001",
            "providernarration": "BeeceptorMy narration",
        "errors    "transaction_final_amount": null1000,
        "error": null,         "provider_response"meta":{
 {             "referencefee_flat": "000022200225154318222333334432"0,
              "destinationfee_institution_codepercent": "000016"0,
              "beneficiarycommission_account_nameflat": "JOHN0,
DOE JAMES",             "beneficiarycommission_account_numberpercent": "3056433222"0,
              "beneficiaryfield_kyc_levelkey": "3field_value",
              "originator_account_name": "James Jane",field_key":"field_value"
            }
  "originator_account_number": "0001131256",      }
        "originator_kyc_level": "1",
            "narration": "My narration",
            "transaction_final_amount": 1000,
            "meta":{
    }
}
Info

NOTE: For a successfully completed transaction the response.data.provider_response.metaobject should at a minimum contain 4 fields:

  • fee_flat: Any flat fee that was charged to the calling client

  • fee_percent: Any percentage-based fee that was charged to the calling client

  • commission_flat: Any flat amount commission paid to the calling client

  • commission_percent: Any percentage-based commission paid to the calling client

A typical /transact/validate request

This is when Providers respond with WaitingForOTP or PendingValidation.

Code Block
languagejson
{
  "request_ref":"{{request_ref}}", 
  "request_type":"lookup_bvn_max",
	"auth": {
        "secure": "fee_flat": 0{{encrypted_otp_orPIN_orOtherInput}}",
              "fee_percent"auth_provider": 0,"Beeceptor" 
    },
        "commission_flat"transaction": 0,
   {
          "commissiontransaction_percentref": 0,
    "70713093460718"
    }
}

A /transact/validate request should typically lead to a completion response (or in some cases: another validate response if appropriate)

A typical /transact/query request

To find out the status of a former transaction

Code Block
languagejson
{
   "field_key":"field_value",
              "field_key":"field_value"
            }
        }
    }
}
Info

NOTE: For a successfully completed transaction the response.data.provider_response.metaobject should at a minimum contain 4 fields:

  • fee_flat: Any flat fee that was charged to the calling client

  • fee_percent: Any percentage-based fee that was charged to the calling client

  • commission_flat: Any flat amount commission paid to the calling client

  • commission_percent: Any percentage-based commission paid to the calling client

A typical /transact/validate request

This is when Providers respond with WaitingForOTP or PendingValidation.

Code Block
languagejson
{
  "request_ref":"{{request_ref}}", 
  "request_type":"lookup_bvn_max",
	"auth": {
        "secure": "{{encrypted_otp_orPIN_orOtherInput}}",
        "auth_provider": "Beeceptor" 
    },
    "transaction": {
        "transaction_ref": "70713093460718"
    }
}

A /transact/validate request should typically lead to a completion response (or in some cases: another validate response if appropriate)

A typical /transact/query request

To find out the status of a former transaction

Code Block
languagejson
{
	"request_ref":"{{request-ref}}",
	"request_type":"{{request_type}}",
	"transaction":{
		"transaction_ref": "12978251696483"
	}
}

A /transact/validate request should typically lead to a completion response (or in some cases: another validate response if appropriate)

A typical /transact/options request

Same payload as the the /transact call, only that it’s probing the provider for options. At this point auth can be null if the provider supports it.

Code Block
languagejson
{
  "request_ref":"{{request_ref}}", 
  "request_type":"transfer_funds",
  "auth": {
    "type": "bank.account | card | wallet", 
    "secure": "{{encrypted(bank account details | card details | wallet)}}",
    "auth_provider": "Beeceptor",
    "route_mode": null
  },
  "transaction": {
    "mock_mode": "live", 
    "transaction_ref": "{{transaction_ref}}", 
    "transaction_desc": "A random transaction", 
    "transaction_ref_parent": null,	"request_ref":"{{request-ref}}",
	"request_type":"{{request_type}}",
	"transaction":{
		"transaction_ref": "12978251696483"
	}
}

A /transact/validate request should typically lead to a completion response (or in some cases: another validate response if appropriate)

A typical /transact/options request

Same payload as the the /transact call, only that it’s probing the provider for options. At this point auth can be null if the provider supports it.

Code Block
languagejson
{
  "request_ref":"{{request_ref}}", 
  "request_type":"transfer_funds",
  "auth": {
    "type": "bank.account | card | wallet", 
    "secure": "{{encrypted(bank account details | card details | wallet)}}",
    "auth_provider": "Beeceptor",
    "route_mode": null
  },
  "transaction": {
    "mock_mode": "live", 
    "transaction_ref": "{{transaction_ref}}", 
    "transaction_desc": "A random transaction", 
    "transaction_ref_parent": null, 
    "amount": 1000,
    "customer":{
    	"customer_ref": "{{customer_id}}",
    	"firstname": "Uju",
        "surname": "Usmanu",
    	"email": "ujuusmanu@gmail.com",
    	"mobile_no": "234802343132"
    },
    "meta":{
    	"a_key":"a_meta_value_1",
    	"another_key":"a_meta_value_2"
    },
    "details": {
    	"a_key":"a_value",
        "a_key":"a_value"
    }
  }
}

A typical /transact/fulfil request

To force-complete a prior transaction that is partially completed. e.g. Airtime in which the customer was debited but the airtime didn't vend.

Code Block
languagejson
{
    "request_ref": "{{request_ref}}",
    "request_type": "{{request type}",
    "request_mode": "fulfil",
    "transaction": {
        "amount": 1000"18000",
    "customer":{     	"customertransaction_ref": "{{customertransaction_idref}}",
    	"firstname": "Uju",         "surname"transaction_desc": "Usmanu{{transaction_desc}}",
    	"email": "ujuusmanu@gmail.com",      	"mobiletransaction_ref_noparent": "234802343132"{{parent_transaction_ref}}",
    },     "metadetails": {...}
      	"a_key":"a_meta_value_1",
    	"another_key":"a_meta_value_2"
    },
    "details": {
    	"a_key":"a_value",
        "a_key":"a_value"
    }
  }
}}
}

A /transact/fulfil request should typically lead to a completion response (or in some cases: another validate response if appropriate)

A typical /transact/reverse request

To rollback a prior completed transaction (when supported by a provider or service)

Code Block
languagejson
{
	"request_ref":"{{request-ref}}",
	"request_type":"{{request_type}}",
	"transaction":{
		"transaction_ref": "12978251696483"
	}
}

Request Payload Description

...

Field

Type

Requirement

Description

status

string

compulsory

Gives the final status of the API call

message

string

compulsory

A message for the API caller, which may or may not be bubbled to the actual user.

data.provider_response_code

string

compulsory

A response code used internally by the provider.

data.provider

string

compulsory

The provider that processed the transaction.

data.error

object

compulsory

The single error that caused a transaction to fail. Can be null for successful transactions.

data.errors

array

compulsory

An array of error objects from the provider, in case multiple errors occurred. Can be null.

data.error.code

string

compulsory

All error objects need to have a code.

data.error.message

string

compulsory

All error objects need to have a message.

data.provider_response

object

compulsory

An object that will encapsulate the actual response data for the provider as described by the standard specification for that service.

data.provider_response.meta

array

optional

In the event that the provider has more information to share that the specification for that transaction type is not covered, providers can put this here. It’s simply a key value pair of anything. It’s expected that apps are aware of what these values and keys might be upfront though. Works for cases where the app knows the details of the provider’s API but the OnePipe spec is inadequate.

data.provider_response.reference

string

optional

In the event that a provider issues its own unique reference for tracing a transaction (for reconciliation purposes), this field should be populated with that value.

...

...

Interface specification (

...

OnePipe → Provider microservice)

Info

Request payload from OnePipe to the provider microservice comes encrypted, using the Triple DES Algorithm. See details.

...