General idea
Background and problem statement
Today at OnePipe, we create unique workflows within GRB that match a specific CX or use case. At times, these workflows call underlying OnePipe APIs, at times they don’t. But they typically achieve a “jobs-to-be-done” goal for the user. One of the challenges we have always grappled with is how at times these workflows seem to precede the actual OnePipe API. And then we try to (in retrospect) figure out how to make such a workflow become API-first afterwards. Examples are: Account upgrade, GroupMoni Pay4Me, Pay-to-App, etc.
Proposed solution
OneChapp (on which GRB is based) today has a public API with which any channel can invoke and execute intents by following a conversation flow.
Send text to an endpoint
Text is matched to an intent and a session is established
Intent executes and sends back a response
Process and present the response in the best way possible
Go back to #1 till service/session is completed.
Now, imagine that we can expose this back & forth flow via the standard api.onepipe.io but present it as a “service” that a OnePipe App can simply call to leverage the logic that we have already encapsulated within the intent.
This way, the API caller never needs to get setup as a channel on OneChapp (or learn full details of OneChapp API), and we can feel free to create proper jobs-to-be-done as intents first and OnePipe apps can leverage this flow first while we figure out how to turn these into standard OnePipe services a bit more measuredly.
Other advantages:
We can iterate (as we currently do) on CX and flows freely in GRB as more facts come to light based on usage
We no longer need to overly constraint CX within GRB (because we want to match standard OnePipe API flow at execution time)
We can now roll out new service bundles faster to any partner that wants reuse some of our logic. e.g. WeKurnect trying to enable pay4me in their platform (current pay4me logic is deep with non-OnePipe API elements)
Process flows
Sequence of calls
App calls
/transact
with the NO auth detailsIn the
details
object, app inserts the user’s message as text + a callback urlProvider responds with
PendingValidation
and a details object corresponding to the message from the underlying intent (text, menu, buttons, attachments)Where the response is delayed: Provider responds via the callback url
App calls
/transact/validate
to supply the user’s choice/textProvider responds with any of the completion codes
Successful
orFailed
if it has all it needs to finish off the intent. Otherwise go back to #3To query the status of a transaction, the app can call
/transact/query
Where the provider supports it, the app can call
/transact/reverse
to request a reversal (if supported)
Before you proceed: Please read this.
INTERFACE SPECIFICATION (APP → ONEPIPE)
For details on encryption using the Triple DES Algorithm, read this.
Request (/transact)
{ "request_ref": "{{request_ref}}", "request_type": "benefits_intent", "auth": { "type": null, "secure": null, "auth_provider": "Benefits", "route_mode": null }, "transaction": { "mock_mode": "live", "transaction_ref": "{{transaction_ref}}", "transaction_desc": "A random transaction", "transaction_ref_parent": null, "amount": 0, "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": { "message": "{{some kain text to trigger the intent or respond to a message}}", "callback_url": "{{a url to post the response to for long running proceses}}", "subsequent_messages": [], //An array of {{message}} elements. Such that if a developer already knows the EXACT set of questions that will follow in order to complete an intent, they can preload it, the provider will hold on their behalf and forward to OneChapp as each response is received. USE CASE: Making it possible to have one-shot API calls. e.g. We can then have Appsolute built a single USSD string to trigger pay4me in one shot when its time for retailer self-service "client_id": "{{app_code of the app}}", //optional "sender_id": "{{customer_ref}}", //optional "channel": "OnePipe", //optional } } }
NOTE: details.message
must be sent encrypted
A NOTE ON subsequent_messages
: An arrangement such that if a developer already knows the EXACT set of questions that will follow in order to complete an intent, they can preload it, the provider will hold the array on their behalf and forward to OneChapp as each response is received from OneChapp. USE CASE: Making it possible to have one-shot API calls. e.g. We can then have Appsolute built a single USSD string to trigger pay4me in one shot when its time for retailer self-service. Or we can have someone call a single API to upgrade an account from level 1 to 3
Response
NOTE: provider_response.action
must be received encrypted
Text
{ "status": "Successful | Failed | PendingValidation", "message": "{{The same value in provider_response.action.message}}", "data": { "provider_response_code": "00", "provider": "Benefits", "errors": null, "error": null, "provider_response": { "reference":"263636363633777", "action": { "recipientId": "2347083108908", "message": { "type": "text", "text": "How much do you need?" }, } "meta":{} } } }
Menu
{ "status": "Successful | Failed | PendingValidation", "message": "{{The same value in provider_response.action.message}}", "data": { "provider_response_code": "00", "provider": "Benefits", "errors": null, "error": null, "provider_response": { "reference":"263636363633777", "action": { "recipientId": "2347083108908", "message": { "type": "menu", "text": "Welcome, how can I help you today?", "menu": [ { "id": "1", "item": "Account Statement" }, { "id": "2", "item": "Ask A Question" }, { "id": "3", "item": "Balance Enquiry" }, { "id": "4", "item": "Bill Payment" } ] }, } "meta":{} } } }
Buttons
{ "status": "Successful | Failed | PendingValidation", "message": "{{The same value in provider_response.action.message}}", "data": { "provider_response_code": "00", "provider": "Benefits", "errors": null, "error": null, "provider_response": { "reference":"263636363633777", "action": { "recipientId": "2347083108908", "message": { "type": "buttons", "text": "Choose a password:", "buttons": [ { "title": "Enter password", "url": "https://f31ac10a.ngrok.io/u/eb087" } ] }, } "meta":{} } } }
Attachments
{ "status": "Successful | Failed | PendingValidation", "message": "{{The same value in provider_response.action.message}}", "data": { "provider_response_code": "00", "provider": "Benefits", "errors": null, "error": null, "provider_response": { "reference":"263636363633777", "action": { "recipientId": "2347083108908", "message": { "type": "attachments", "text": "Hi user, here are some sample attachments.", "attachments": [ { "type": "pdf", "url": "http://164.100.133.129:81/econtent/Uploads/Session3%20Classification%20of%20Car%20by%20Body%20Style.pdf" }, { "type": "image", "url": "https://www.summerhilllandscapes.com/wp-content/uploads/2016/10/SFrances_160726_3934_A.jpg" } ] }, } "meta":{} } } }
Request (/validate)
{ "request_ref":"{{request_ref}}", "request_type":"benefits_intent", "auth": { "secure": "{{the message or selection from the user}}", "auth_provider": "Benefits" }, "transaction": { "transaction_ref": "70713093460718" } }
Acceptable values for auth.type
Type | Description |
---|---|
null | Auth type always set to null (but we would setup the App’s OneChapp creds as extras variables?) |
Possible status response codes
For this service, these are the possible responses a client can receive
Status | Meaning |
---|---|
Successful | Standard success code |
Failed | Standard failure code |
PendingValidation | To signify that this provider needs some extra information to be provided. The |
INTERFACE SPECIFICATION (ONEPIPE → PROVIDER MICRO SERVICE)
Request payload from OnePipe to the provider microservice comes encrypted, using the Triple DES Algorithm. See details.
Read this closely.
Settlement & fees model
We can choose to charge a small fee like N2 for each completed intent. But if a OnePipe API is used underneath, it will carry it’s own pricing logic.
Model | How it works |
---|---|
Invoice | The host client will invoice the calling app periodically for all calls to the endpoint. |
0 Comments