Package: k2-connect
k2-connect-pythonk2-connect is a Python library for accessing the Kopo Kopo APIs.InstallationUse the package managerpipto install k2connect.pip3installk2-connectUsageInitializationThe library is initialized once then all services maybe accessed by creating different instances for specific services.
TheBASE_URLis a custom value and any url maybe passed provided it is secured and should only be accessible over TLS (HTTPS) and your server should have a valid certificate.
Initialization requires the following arguments:base_urlclient_idclient_secretimportosimportk2connectCLIENT_ID='my_client_id'CLIENT_SECRET=os.getenv('MY_CLIENT_SECRET')BASE_URL='https://sandbox.kopokopo.com/'#initialize the libraryk2connect.initialize(CLIENT_ID,CLIENT_SECRET,BASE_URL)k2connect servicesAfter initialization, k2connect services may be accessed by creating instances of a specific service. For instance:# create an instance of the serviceauthenticator=k2connect.Tokens# access a method provided by the serviceauthenticator.request_access_token()One can access the following k2connect services:TokensServicePayServiceReceivePaymentsServiceTransferServiceWebhookServiceNotificationServicePollingServiceToken serviceThe token service allows you to request access tokens that you will use in order to communicate with the Kopo Kopo APIs.
The token service avails the option for you to implement token refresh mechanism by providing the duration within which
the token will expire.Theget_access_token()andget_token_expiry_duration()methods each take a response object from which they extract the
token and expiry duration values.A request token and expiry duration time can be gotten as follows:# create an instance of the token servicetoken_service=k2connect.Tokens# request the access tokenaccess_token_request=token_service.request_access_token()# get access tokenaccess_token=token_service.get_access_token(access_token_request)# get expiry durationtoken_expiry_duration=token_service.get_token_expiry_duration(access_token_request)Pay serviceThe pay service enables you to add external entities (recipients) as destinations for payments made withe the pay service.
It also enables you to make payments and check for a payment's status.To add pay recipients theadd_pay_recipient()method is used. The currently supported recipient types arebank_accountandmobile_walletthe method then takes a set of key worded arguments required to create a recipient of either type. The accepted
key worded arguments are as follows:Forbank_accountrecipient:account_nameREQUIREDaccount_numberREQUIREDbank_branch_refREQUIREDsettlement_methodREQUIREDFormobile_walletrecipient:first_nameREQUIREDlast_nameREQUIREDphoneREQUIREDemailREQUIREDnetworkREQUIREDFortillrecipient:till_nameREQUIREDtill_numberREQUIREDForpaybillrecipient:paybill_nameREQUIREDpaybill_numberREQUIREDpaybill_account_numberREQUIREDTo send payments thesend_pay()method is used. It takes the following arguments:bearer_tokenREQUIREDcallback_urlREQUIREDdestinationREQUIREDamountREQUIREDdescriptionREQUIREDcurrency='KES'REQUIREDmetadataOPTIONAL. Maximum 5 dictionaries/hashes/key-value pairs.Note: the currency argument is set toKESas the default currency since that is the only ISO currency currently supported. It may however,
be overridden by passing a different currency value in its place. If you do not wish to override theKEScurrency you can simply avoid
passing it as an argument.The pay service also enables you to check the status of a transaction by querying a URL that points to the transaction resource, using thepay_transaction_status().The Resource Location URL is returned by the either of the methods.# create an instance of the pay servicepay_service=k2connect.Pay# create bank account pay recipientbank_recipient_request={"access_token":'ACCESS_TOKEN',"recipient_type":'bank_account',"settlement_method":"EFT","account_name":"bank_account_name","bank_branch_ref":"633aa26c-7b7c-4091-ae28-96c0687cf886","account_number":"bank_account_number"}bank_pay_location=pay_service.add_pay_recipient(bank_recipient_request)# create mobile wallet pay recipientmobile_recipient_request={"access_token":'ACCESS_TOKEN',"recipient_type":'mobile_wallet',"first_name":"mobile_wallet_first_name","last_name":"mobile_wallet_last_name","phone_number":"+254123456789","network":"mobile_wallet_network","email":"test@test.com"}mobile_pay_location=pay_service.add_pay_recipient(mobile_recipient_request)# create till pay recipienttill_recipient_request={"access_token":"ACCESS_TOKEN","recipient_type":"till","till_name":"till_name","till_number":"till_number",}till_pay_location=pay_service.add_pay_recipient(till_recipient_request)# create paybill pay recipientpaybill_recipient_request={"access_token":"ACCESS_TOKEN","recipient_type":"paybill","paybill_name":"paybill_name","paybill_number":"paybill_number","paybill_account_number":"account_number",}paybill_pay_location=pay_service.add_pay_recipient(paybill_recipient_request)# send pay transaction to mobile walletrequest_payload={"access_token":'ACCESS_TOKEN',"destination_reference":'9764ef5f-fcd6-42c1-bbff-de280becc64b',"destination_type":'mobile_wallet',"callback_url":'https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d',"amount":'10',"currency":'KES',"metadata":{"hey":'there',"mister":'angelo'}}create_mobile_pay_location=pay_service.send_pay(request_payload)# send pay transaction to bank accountrequest_payload={"access_token":'ACCESS_TOKEN',"destination_reference":'9764ef5f-fcd6-42c1-bbff-de280becc64b',"destination_type":'bank_account',"callback_url":'https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d',"amount":'10',"currency":'KES',"metadata":{"hey":'there',"mister":'angelo'}}create_bank_pay_location=pay_service.send_pay(request_payload)# send pay transaction to tillrequest_payload={"access_token":'ACCESS_TOKEN',"destination_reference":'9764ef5f-fcd6-42c1-bbff-de280becc64b',"destination_type":'till',"callback_url":'https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d',"amount":'10',"currency":'KES',"metadata":{"hey":'there',"mister":'angelo'}}create_till_pay_location=pay_service.send_pay(request_payload)# send pay transaction to paybill accountrequest_payload={"access_token":'ACCESS_TOKEN',"destination_reference":'9764ef5f-fcd6-42c1-bbff-de280becc64b',"destination_type":'paybill',"callback_url":'https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d',"amount":'10',"currency":'KES',"metadata":{"hey":'there',"mister":'angelo'}}create_paybill_pay_location=pay_service.send_pay(request_payload)# get payment request statuspay_request_status=pay_service.pay_transaction_status(access_token,create_mobile_pay_location)Receive payments serviceThe receive payments service allows you to create requests for incoming payments over a specific channel and receive the payments
to your account. You can also check the status of your payment requests and access the payment request through a URL.In order to create a payment request, thecreate_payment_request()method is used. This method can be passed the following arguments:bearer_tokenREQUIREDcallback_urlREQUIREDfirst_nameREQUIREDlast_nameREQUIREDpayment_channelREQUIREDphoneREQUIREDtill_numberREQUIREDvalueREQUIREDcurrency='KES'REQUIREDmetadataOPTIONAL. Maximum 5 dictionaries/hashes/key-value pairs.Note: the currency argument is set toKESas the default currency since that is the only ISO currency currently supported. It may however,
be overridden by passing a different currency value in its place. If you do not wish to override theKEScurrency you can simply avoid
passing it as an argument.The method also creates the provision for optionalemailinformation to be passed in the key worded argument form,
for instance:email='mycool@email.domain'Furthermore, thecreate_payment_request()allows you to add metadata information passed in the form of a maximum of 5 key worded arguments.The URL required for checking a payment request status is returned by default with thecreate_payment_requestmethod.importos# get the access tokenBEARER_TOKEN=os.getenv('MY_BEARER_TOKEN')# create an instance of the receive payments servicereceive_payments_service=k2connect.ReceivePayments# create a payment requestrequest_payload={"access_token":'ACCESS_TOKEN',"callback_url":"https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d","first_name":"python_first_name","last_name":"python_last_name","email":"daivd.j.kariuki@gmail.com","payment_channel":"MPESA","phone_number":"+254911222536","till_number":"K112233","amount":"10","metadata":{"hey":'there',"mister":'angelo'}}mpesa_payment_location=receive_payments_service.create_payment_request(request_payload)# get payment request statuspayment_request_status=receive_payments_service.payment_request_status(access_token,mpesa_payment_location)Transfers serviceThe transfer service enables you to create verified settlement mobile and bank accounts with respectiveadd_settlement_account()methods. The method takes the following arguments:Common for both:bearer_tokenREQUIREDForadd_bank_settlement_account:account_nameREQUIREDaccount_numberREQUIREDbank_idREQUIREDbank_branch_idREQUIREDForadd_mobile_wallet_settlement_accountrecipient:msisdnREQUIREDnetwork: 'Safaricom'REQUIREDThe transfer service enables you to transfer funds to these pre-approved settlement accounts. To settle funds thesettle_funds()is used. It enables you to make two types of transfer
transactions, a blind settlement and a targeted settlement. A blind transaction is made with thedestinationargument set toNone, in the event that an ID for the destination of funds
is provided then a targeted transfer is made to that destination. The method takes the following arguments:bearer_tokenREQUIREDtransfer_valueREQUIREDtransfer_currency = 'KES'REQUIREDdestination_typeOPTIONALdestination_referenceOPTIONALNote: the currency argument is set toKESas the default currency since that is the only ISO currency currently supported. It may however,
be overridden by passing a different currency value in its place. If you do not wish to override theKEScurrency you can simply avoid
passing it as an argument.You can check a transfer transaction's status by querying the transaction resource's location
URL which is returned by thesettle_fundsmethod by default.Thetransfer_transaction_status()method is then used to check a transfer transaction status.# initialize the transfer servicetransfer_service=k2connect.Transfers# create verified settlement bank accountrequest_payload={"access_token":'ACCESS_TOKEN',"settlement_method":'RTS',"account_name":'py_sdk_account_name',"account_number":'py_sdk_account_number',"bank_branch_ref":'633aa26c-7b7c-4091-ae28-96c0687cf886'}settlement_account=transfer_service.add_bank_settlement_account(request_payload)# create verified settlement mobile accountrequest_payload={"access_token":'ACCESS_TOKEN',"first_name":'py_sdk_first_name',"last_name":'py_sdk_last_name',"phone_number":'+254911222538',"network":'Safaricom'}settlement_account=transfer_service.add_mobile_wallet_settlement_account(request_payload)# settle funds (blind transfer)request_payload={"access_token":'ACCESS_TOKEN',"callback_url":'url',"value":'10',}transfer_transaction=transfer_service.settle_funds(request_payload)# settle funds (targeted transfer to a merchant_wallet)request_payload={"access_token":'ACCESS_TOKEN',"destination_type":'merchant_bank_account',"destination_reference":'87bbfdcf-fb59-4d8e-b039-b85b97015a7e',"callback_url":'https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d',"value":'10',}transfer_transaction_mobile_location=transfer_service.settle_funds(request_payload)# settle funds (targeted transfer to a merchant_wallet)request_payload={"access_token":'ACCESS_TOKEN',"destination_type":'merchant_wallet',"destination_reference":'eba238ae-e03f-46f6-aed5-db357fb00f9c',"callback_url":'https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d',"value":'10',}transfer_transaction_bank_location=transfer_service.settle_funds(request_payload)# get transfer transaction statustransfer_transaction_status=transfer_service.transfer_transaction_status(access_token,transfer_transaction_mobile_locationortransfer_transaction_bank_location)The destination_reference number corresponding to a settlement account must exist before you can settle_funds to it.Webhook serviceThe webhook service allows you to create subscriptions to events that occur on the KopoKopo application. Thecreate_subscription()method is used,
it takes the following arguments:bearer_tokenREQUIREDevent_typeREQUIREDwebhook_endpointREQUIREDclient_secretREQUIREDCurrently the following events are supported:b2b_transaction_receivedbuygoods_transaction_receivedbuygoods_transaction_reversedm2m_transaction_receivedsettlement_transfer_completedcustomer_createdimportos# initialize servicewebhook_service=k2connect.Webhooksrequest_payload={"access_token":'ACCESS_TOKEN',"event_type":'buygoods_transaction_received',"webhook_endpoint":'https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d',"scope":'till',"scope_reference":'112233'}# create webhook subscriptioncustomer_created_subscription=webhook_service.create_subscription(request_payload)Notification serviceThis service allows you to send custom sms messages to successful buy-goods transactions received that occurred on the Kopo Kopo.
It takes the following arguments:bearer_tokenREQUIREDwebhookEventReference: The webhook event reference for a buygoods_transaction_received webhook.REQUIREDmessage: The message to be sentREQUIREDcallbackUrl: Url that the result will be posted toREQUIREDNote: A buygoods_transaction_received webhook subscription must have been created, with its subsequent webhook event in place.You can check an SMS notification request's status by querying the requests' location
URL which is returned by thesend_transaction_sms_notificationmethod by default.Thetransaction_notification_status()method is used to check an SMS notification request status.importos# initialize notification servicenotification_service=k2connect.Notifications# create transaction sms notificationsrequest_payload={"access_token":'ACCESS_TOKEN',"callback_url":'callback_url',"webhook_event_reference":"d81312b9-4c0e-4347-971f-c3d5b14bdbe4","message":'Alleluia',}notification_resource_location_url=notification_service.send_transaction_sms_notification(request_payload)# get request statusrequest_status=notification_service.transaction_notification_status(access_token,notification_resource_location_url)Polling serviceThis service allows you to poll transactions received on the Kopo Kopo system within a certain time range, and either a company or a specific till.
It takes the following arguments:bearer_tokenREQUIREDfromTime: The starting time of the polling requestREQUIREDtoTime: The end time of the polling requestREQUIREDscope: The scope of the polling requestREQUIREDscopeReference: The scope referenceREQUIRED for the 'till' scopecallbackUrl: Url that the result will be posted toREQUIREDYou can check a polling request's status by querying the requests' location
URL which is returned by thecreate_polling_requestmethod by default.Thepolling_request_status()method is used to check an polling request status.importos# initialize servicenotification_service=k2connect.Polling# create polling requestrequest_payload={"access_token":'ACCESS_TOKEN',"callback_url":'callback_url',"scope":"till","scope_reference":"112233","from_time":"2021-07-09T08:50:22+03:00","to_time":"2021-07-10T18:00:22+03:00",}polling_resource_location_url=notification_service.send_transaction_sms_notification(request_payload)# get request statusrequest_status=notification_service.transaction_notification_status(access_token,polling_resource_location_url)For more information, please readTransaction Notification DocsResult processorResults (inclusive of webhook results and results posted to callback URLs asynchronously) sent from KopoKopo have to be processed before payloads can
be accessed. The result processor can be used to accomplish this using theprocess()method.# initialize result handlerresult_handler=k2connect.ResultHandler# process resultprocessed_payload=result_handler.process(some_result)Payload decomposerOnce a result is processed an a payload has been returned, it can be decomposed into its constituent result data using the payload decomposer.
The payload decomposer achieves this using thedecompose()method.fromk2connectimportpayload_decomposer# decompose a payloaddecomposer=payload_decomposer.decompose(processed_payload)# get first namefirst_name=decomposer.first_nameAuthorThis library was written byPhilipWafulaandDavid Kariuki Mwangi.ContributingBug reports and pull requests are welcome. Feel free raise issues on ourissues trackerLicensek2connect-python isMITLicensed.Changelog