def transfers(transfer_links, transfers_amount, **kwargs): """ Returns JSON formatted containing information about a transfer. :param transfers_amount: Amount to be transferred. :type transfers_amount: str :param transfer_links: Links containing Callback URL. :type transfer_links: str :param kwargs: Provision for optional 'destination' value. :type kwargs: str :return: str """ # validate string arguments validation.validate_string_arguments(*transfer_links, *transfers_amount) if 'destination_type' not in kwargs: destination_type = None else: destination_type = kwargs['destination_type'] if 'destination_reference' not in kwargs: destination_reference = None else: destination_reference = kwargs['destination_reference'] transfers_object = { 'amount': transfers_amount, 'destination_reference': destination_reference, 'destination_type': destination_type, '_links': transfer_links } return transfers_object
def polling(scope, scope_reference, from_time, to_time, polling_links): """ Returns JSON formatted containing information about a transfer. :param scope: Amount to be transferred. :type scope: str :param scope_reference: Links containing Callback URL. :type scope_reference: str :param from_time: Defines the beginning start time. :type from_time: str :param to_time: Defines the beginning end time. :type to_time: str :param polling_links: Contains callback_url. :type polling_links: str :return: str """ # validate string arguments validation.validate_string_arguments(*scope, *scope_reference, *from_time, *to_time, *polling_links) transfers_object = { 'scope': scope, 'scope_reference': scope_reference, 'from_time': from_time, 'to_time': to_time, '_links': polling_links } return transfers_object
def subscriber(first_name, last_name, phone_number, email, **kwargs): """ Returns JSON formatted str containing subscriber information :param first_name: First name of the subscriber :type first_name: str :param last_name: Last name of the subscriber :type last_name: str :param phone_number: Phone number of the subscriber from which the pay will be made :type phone_number: str :param email: Email of the subscriber :type email: str :param kwargs: Provision for optional 'email' information. :type kwargs: str :return: str """ # validate string arguments validation.validate_string_arguments(first_name, last_name, phone_number) if email != "Null": validation.validate_email(email) # if 'email' not in kwargs: # email = 'Null' # else: # email = kwargs['email'] subscriber_object = { 'first_name': first_name, 'last_name': last_name, 'phone_number': phone_number, 'email': email } return subscriber_object
def _query_transaction_status(self, bearer_token, query_url): """ Returns a JSON object result containing the transaction status. :param bearer_token: Access token to be used to make calls to the Kopo Kopo API :type bearer_token: str :param query_url: URL to which status query is made. :type query_url: str :return: str """ # define headers _headers = dict(self._headers) # check bearer token validation.validate_string_arguments(bearer_token, query_url) # add bearer token _headers['Authorization'] = 'Bearer ' + bearer_token + '' # validate url validation.validate_url(query_url) return self._make_requests(url=query_url, method='GET', headers=_headers)
def mobile_wallet(first_name, last_name, phone_number, network, **kwargs): """ Returns a json formatted str with the optional value of email. Checks if optional value is present, else passes values as null. :param first_name: First name of the recipient. :type first_name: str :param last_name: Last name of the recipient. :type last_name: str :param phone_number: Phone number of recipient. :type phone_number: str :param network: The mobile network to which the phone number belongs. :type network: str :param kwargs: Provision for optional 'email' value :type kwargs: kwargs :return: """ # validate string arguments validation.validate_string_arguments(first_name, last_name, phone_number, network) if 'email' not in kwargs: email = 'Null' else: email = kwargs['email'] mobile_wallet_object = { 'first_name': first_name, 'last_name': last_name, 'phone_number': phone_number, 'network': network, 'email': email } return mobile_wallet_object
def webhook_subscription(event_type, webhook_endpoint, scope, scope_reference=None): """ Returns JSON formatted str containing webhook subscription information :param event_type:The type of event subscribed to. :type event_type: str :param webhook_endpoint: The HTTP end point to send the webhook. :type webhook_endpoint: str :param scope: A string that will be used to specify whether account is at Till or Company level. :type scope: str :param scope_reference: A string that represents the account number (eg MPESA till number). :type scope_reference: str :return: str """ # validate string arguments validation.validate_string_arguments(event_type, webhook_endpoint, scope) if scope_reference is not None: validation.validate_string_arguments(scope_reference) webhook_subscription_object = { 'event_type': event_type, 'url': webhook_endpoint, 'scope': scope, 'scope_reference': scope_reference } return webhook_subscription_object
def bank_account(account_name, account_number, settlement_method, bank_branch_ref, **kwargs): """ Returns a json formatted str with the optional value of email and phone. Checks if optional values are present, else passes values as null. :param account_name: Name as indicated on the bank account name. :type account_name: str :param account_number: Bank account number. :type account_number: str :param bank_branch_ref: Identifier identifying the destination bank branch. :type bank_branch_ref: str :param settlement_method: Whether bank account can settle via EFT or RTS :type settlement_method: str :param kwargs: Provision for optional 'email' and 'phone' information. :type kwargs: kwargs :return: str """ # validate string arguments validation.validate_string_arguments(account_name, account_number, settlement_method, bank_branch_ref) bank_account_object = { 'account_name': account_name, 'account_number': account_number, 'settlement_method': settlement_method, 'bank_branch_ref': bank_branch_ref } return bank_account_object
def create_polling_request(self, kwargs): """ Creates a request for the reception of payments from MPESA users. Returns a request response object < class, 'requests.models.Response'> :param kwargs: The values constitute all user input. :type kwargs: dict :return: requests.models.Response """ if 'access_token' not in kwargs: raise exceptions.InvalidArgumentError('Access Token not given.') if 'scope' not in kwargs or \ 'scope_reference' not in kwargs or \ 'from_time' not in kwargs or \ 'to_time' not in kwargs or \ 'callback_url' not in kwargs: raise exceptions.InvalidArgumentError( 'Invalid arguments for creating Polling Request.') # iterate through kwargs if 'access_token' in kwargs: bearer_token = kwargs['access_token'] if 'scope' in kwargs: scope = kwargs['scope'] if 'scope_reference' in kwargs: scope_reference = kwargs['scope_reference'] if 'from_time' in kwargs: from_time = kwargs['from_time'] if 'to_time' in kwargs: to_time = kwargs['to_time'] if 'callback_url' in kwargs: callback_url = kwargs['callback_url'] # define headers headers = dict(self._headers) # validate bearer_token validation.validate_string_arguments(bearer_token) # add bearer token headers['Authorization'] = 'Bearer ' + bearer_token + '' # build polling request url polling_request_url = self._build_url(POLLING_PATH) # define links JSON object polling_request_links = json_builder.links(callback_url=callback_url) # define MPESA payment request JSON object polling_request_payload = json_builder.polling( scope=scope, scope_reference=scope_reference, from_time=from_time, to_time=to_time, polling_links=polling_request_links) return self._make_requests(headers=headers, method='POST', url=polling_request_url, payload=polling_request_payload)
def send_pay(self, bearer_token, callback_url, destination, value, currency='KES', **kwargs): """ Creates an outgoing pay to a third party. The result of the pay is provided asynchronously and posted to the callback_url provided. Returns a request response object < class, 'requests.models.Response'> :param bearer_token: Access token to be used to make calls to the Kopo Kopo API :type bearer_token: str :param callback_url: :type callback_url: str :param destination: ID of the destination of funds. :type destination: str :param value: Value of money to be sent (child of amount JSON str) :type value: str :param currency: Currency of amount being transacted :type currency: str :param kwargs: Provision for optional metadata with maximum of 5 key value pairs. :type kwargs: dict :return:requests.models.Response """ # build send_pay url send_pay_url = self._build_url(SEND_PAY_PATH) # define headers headers = dict(self.headers) # check bearer token validation.validate_string_arguments(bearer_token) # add authorization to headers headers['Authorization'] = 'Bearer ' + bearer_token + '' # create amount json object pay_amount = json_builder.amount(currency=currency, value=value) # create metadata json object pay_metadata = json_builder.metadata(', '.join( ['{}={}'.format(k, v) for k, v in kwargs.items()])) # create links json object pay_links = json_builder.links(callback_url=callback_url) # create payment json object pay_json = json_builder.pay(destination, pay_amount, pay_metadata, pay_links) return self._make_requests(url=send_pay_url, method='POST', payload=pay_json, headers=headers)
def add_mobile_wallet_settlement_account(self, kwargs): """ Creates a verified settlement bank account. Returns a request response object < class, 'requests.models.Response'> :param kwargs: The values constitute all user input. :type kwargs: dict :return: requests.models.Response """ if 'access_token' not in kwargs: raise exceptions.InvalidArgumentError('Access Token not given.') if 'first_name' not in kwargs or \ 'last_name' not in kwargs or \ 'phone_number' not in kwargs or \ 'network' not in kwargs: raise exceptions.InvalidArgumentError( 'Invalid arguments for creating Outgoing Pay.') # iterate through kwargs if 'access_token' in kwargs: bearer_token = kwargs['access_token'] if 'first_name' in kwargs: first_name = kwargs['first_name'] if 'last_name' in kwargs: last_name = kwargs['last_name'] if 'phone_number' in kwargs: phone_number = kwargs['phone_number'] if 'network' in kwargs: network = kwargs['network'] # build url create_mobile_wallet_settlement_account_url = self._build_url( SETTLEMENT_MOBILE_ACCOUNTS_PATH) # define headers headers = dict(self._headers) # validate string arguments validation.validate_string_arguments(bearer_token, first_name, last_name, phone_number, network) validation.validate_phone_number(phone_number) # add authorization to headers headers['Authorization'] = 'Bearer ' + bearer_token + '' # define create mobile settlement account payload create_mobile_settlement_account_payload = json_builder.mobile_settlement_account( first_name=first_name, last_name=last_name, phone_number=phone_number, network=network) return self._make_requests( headers=headers, method='POST', url=create_mobile_wallet_settlement_account_url, payload=create_mobile_settlement_account_payload)
def create_subscription(self, bearer_token, event_type, webhook_endpoint, webhook_secret): """ Creates a subscription to a webhook service. Returns a request response object < class, 'requests.models.Response'> :param bearer_token: Access token to be used to make calls to the Kopo Kopo API :type bearer_token: str :param event_type:Type of subscription event. Should be one of: buygoods_transaction_received, buygoods_transaction_reversed, settlement_transfer_completed, customer_created :type event_type: str :param webhook_endpoint: HTTP end point to send the webhook. :type webhook_endpoint: str :param webhook_secret: Secret used to encrypt the request payload using HMAC. :type webhook_secret: str :return: requests.models.Response """ # event types event_types_to_check = [ 'b2b_transaction_received', 'buygoods_transaction_received', 'buygoods_transaction_reversed', 'merchant_to_merchant_transaction_received', 'settlement_transfer_completed', 'customer_created' ] # build subscription url subscription_url = self._build_url(WEBHOOK_SUBSCRIPTION_PATH) # define headers headers = dict(self.headers) # validate string arguments validation.validate_string_arguments(bearer_token, event_type, webhook_endpoint, webhook_secret) headers['Authorization'] = 'Bearer ' + bearer_token + '' if not any(check in event_type for check in event_types_to_check): raise exceptions.InvalidArgumentError( 'Event type not recognized by k2-connect') # validate webhook endpoint validation.validate_url(webhook_endpoint) # define subscription payload subscription_payload = json_builder.webhook_subscription( event_type=event_type, webhook_endpoint=webhook_endpoint, webhook_secret=webhook_secret) return self._make_requests(headers=headers, method='POST', url=subscription_url, payload=subscription_payload)
def add_bank_settlement_account(self, kwargs): """ Creates a verified settlement bank account. Returns a request response object < class, 'requests.models.Response'> :return: requests.models.Response """ if 'access_token' not in kwargs: raise exceptions.InvalidArgumentError('Access Token not given.') if 'settlement_method' not in kwargs or \ 'account_name' not in kwargs or \ 'account_number' not in kwargs or \ 'bank_branch_ref' not in kwargs: raise exceptions.InvalidArgumentError( 'Invalid arguments for creating Bank Settlement Account.') # iterate through kwargs if 'access_token' in kwargs: bearer_token = kwargs['access_token'] if 'settlement_method' in kwargs: settlement_method = kwargs['settlement_method'] if 'account_name' in kwargs: account_name = kwargs['account_name'] if 'account_number' in kwargs: account_number = kwargs['account_number'] if 'bank_branch_ref' in kwargs: bank_branch_ref = kwargs['bank_branch_ref'] # build url create_bank_settlement_account_url = self._build_url( SETTLEMENT_BANK_ACCOUNTS_PATH) # define headers headers = dict(self._headers) # validate string arguments validation.validate_string_arguments(bearer_token, settlement_method, account_name, bank_branch_ref, account_number) # add authorization to headers headers['Authorization'] = 'Bearer ' + bearer_token + '' # define create bank settlement account payload create_bank_settlement_account_payload = json_builder.bank_settlement_account( settlement_method=settlement_method, account_name=account_name, account_number=account_number, bank_branch_ref=bank_branch_ref) return self._make_requests( headers=headers, method='POST', url=create_bank_settlement_account_url, payload=create_bank_settlement_account_payload)
def amount(currency, value): """ Returns json formatted str containing currency and value. :param currency: Currency of amount :type currency: str :param value: Value of money :type value: str :return: str """ # validate str arguments validation.validate_string_arguments(currency, value) amount_object = {'currency': currency, 'value': value} return amount_object
def links(callback_url): """ Validates url passed. Returns a str containing a callback_url. :param callback_url: Callback URL to post result. :type callback_url: str :return: str """ # validate string argument validation.validate_string_arguments(callback_url) # validate url value validation.validate_url(callback_url) links_object = {'callback_url': callback_url} return links_object
def pay_recipient(recipient_type, recipient): """ Returns json formatted str containing pay recipient object. :param recipient_type: Type of recipient eg. mobile wallet or bank account :type recipient_type: str :param recipient: JSON formatted str containing details of the recipient :type recipient: str :return: str """ # validate string arguments validation.validate_string_arguments(*recipient, recipient_type) recipient_object = {'type': recipient_type, 'pay_recipient': recipient} return recipient_object
def settle_funds(self, bearer_token, transfer_value, transfer_currency='KES', transfer_destination=None): """ Creates a transfer from merchant account to a different settlement account. Returns a request response object < class, 'requests.models.Response'> :param bearer_token: Access token to be used to make calls to the Kopo Kopo API :type bearer_token: str :param transfer_currency: Currency of amount being transacted :type transfer_currency: str :param transfer_value: :type transfer_value:Value of money to be sent. :param transfer_destination: str :type transfer_destination: ID of the destination of funds :return: requests.models.Response """ # build settle funds url settle_funds_url = self._build_url(TRANSFER_PATH) # define headers headers = dict(self.headers) # check bearer token validation.validate_string_arguments(bearer_token, transfer_currency, transfer_value) # add authorization to headers headers['Authorization'] = 'Bearer ' + bearer_token + '' # define amount transfer_amount = json_builder.amount(currency=transfer_currency, value=transfer_value) if transfer_destination is None: settle_funds_payload = json_builder.transfers(transfers_amount=transfer_amount) else: settle_funds_payload = json_builder.transfers(transfers_amount=transfer_amount, transfer_destination=transfer_destination) return self._make_requests(headers=headers, method='POST', url=settle_funds_url, payload=settle_funds_payload)
def send_transaction_sms_notification(self, kwargs): """ Creates a transaction sms notification. Returns a request response object < class, 'requests.models.Response'> :return: requests.models.Response """ if 'access_token' not in kwargs: raise exceptions.InvalidArgumentError('Access Token not given.') if 'webhook_event_reference' not in kwargs or \ 'message' not in kwargs or \ 'callback_url' not in kwargs: raise exceptions.InvalidArgumentError('Invalid arguments for creating Transaction SMS Notification.') # iterate through kwargs if 'access_token' in kwargs: bearer_token = kwargs['access_token'] if 'webhook_event_reference' in kwargs: webhook_event_reference = kwargs['webhook_event_reference'] if 'message' in kwargs: message = kwargs['message'] if 'callback_url' in kwargs: callback_url = kwargs['callback_url'] # build url create_transaction_sms_notification_url = self._build_url(TRANSACTION_NOTIFICATIONS_PATH) # define headers headers = dict(self._headers) # validate string arguments validation.validate_string_arguments(bearer_token, webhook_event_reference, message, callback_url) notification_links = json_builder.links(callback_url=callback_url) # add authorization to headers headers['Authorization'] = 'Bearer ' + bearer_token + '' # define create bank settlement account payload create_transaction_sms_notification_payload = json_builder.transaction_sms_notification(webhook_event_reference=webhook_event_reference, message=message, notification_links=notification_links) return self._make_requests(headers=headers, method='POST', url=create_transaction_sms_notification_url, payload=create_transaction_sms_notification_payload)
def till_pay_recipient(till_name, till_number): """ Returns a json formatted str with the optional value of email. Checks if optional value is present, else passes values as null. :param till_name: First name of the recipient. :type till_name: str :param till_number: Last name of the recipient. :type till_number: str :return: """ # validate string arguments validation.validate_string_arguments(till_name, till_number) till_pay_recipient_object = { 'till_name': till_name, 'till_number': till_number } return till_pay_recipient_object
def __init__(self, base_url, client_id, client_secret): """ Initializes class and inherits all necessary values from super class initialization as passed in the library initialization function. :param base_url: The domain to use in the library. :type base_url: str :param client_id: Identifier for the k2 user. :type client_id: str :param client_secret: Secret key for k2 user. :type client_secret: str """ validation.validate_string_arguments(base_url, client_id, client_secret) super(TokenService, self).__init__(base_url) self._client_id = client_id self._client_secret = client_secret
def add_settlement_account(self, bearer_token, account_name, account_number, bank_ref, bank_branch_ref): """ Creates a verified settlement bank account. Returns a request response object < class, 'requests.models.Response'> :param bearer_token :type bearer_token: str :param account_name: The name as indicated on the bank account name :type account_name: str :param bank_ref: An identifier identifying the destination bank :type bank_ref: str :param bank_branch_ref: An identifier identifying the destination bank branch :type bank_branch_ref: str :param account_number: The bank account number :type account_number: str :return: requests.models.Response """ # build url create_settlement_account_url = self._build_url(SETTLEMENT_ACCOUNTS_PATH) # validate string arguments validation.validate_string_arguments(bearer_token, account_name, bank_ref, bank_branch_ref, account_number) # add authorization to headers headers['Authorization'] = 'Bearer ' + bearer_token + '' # define create settlement account payload create_settlement_account_payload = json_builder.bank_settlement_account(account_name=account_name, account_number=account_number, bank_branch_ref=bank_branch_ref, bank_ref=bank_ref) return self._make_requests(headers=headers, method='POST', url=create_settlement_account_url, payload=create_settlement_account_payload)
def mpesa_payment(mpesa_links, mpesa_payment_amount, mpesa_payment_subscriber, payment_channel, till_number, **kwargs): """ Returns JSON formatted str with optional 'metadata' JSON str object. :param mpesa_links: A JSON object containing the call back URL :type mpesa_links: str :param payment_channel: Payment channel e.g MPESA :type payment_channel: str :param till_number: Till to which the pay is made. :type till_number: str :param mpesa_payment_subscriber: Subscriber JSON object. :type mpesa_payment_subscriber str :param mpesa_payment_amount: Amount JSON object. :type mpesa_payment_amount str :param kwargs: Optional JSON object containing a maximum of 5 key value pairs. :return: str """ # validate string arguments validation.validate_string_arguments(*mpesa_links, *mpesa_payment_amount, *mpesa_payment_subscriber, *payment_channel, *till_number) if 'metadata' not in kwargs: mpesa_payment_metadata = {} else: mpesa_payment_metadata = kwargs['metadata'] mpesa_payment_object = { 'payment_channel': payment_channel, 'till_number': till_number, 'subscriber': mpesa_payment_subscriber, 'amount': mpesa_payment_amount, 'metadata': mpesa_payment_metadata, '_links': mpesa_links } return mpesa_payment_object
def transaction_sms_notification(webhook_event_reference, message, notification_links): """ Returns JSON formatted containing information about a transfer. :param webhook_event_reference: Reference for webhook event. :type webhook_event_reference: str :param message: Message to be sent. :type message: str :param notification_links: Links containing callback URL. :type notification_links: str :return: str """ # validate string arguments validation.validate_string_arguments(*webhook_event_reference, *message, *notification_links) transaction_sms_notification_object = { 'webhook_event_reference': webhook_event_reference, 'message': message, '_links': notification_links } return transaction_sms_notification_object
def mobile_settlement_account(first_name, last_name, phone_number, network): """ Returns a json formatted str with bank settlement account information. :param first_name: First name of the recipient. :type first_name: str :param last_name: Last name of the recipient. :type last_name: str :param phone_number: The mobile phone number :type phone_number: str :param network: The bank account number :type network: str """ # validate string arguments validation.validate_string_arguments(first_name, last_name, phone_number, network) mobile_settlement_account_object = { 'first_name': first_name, 'last_name': last_name, 'phone_number': phone_number, 'network': network } return mobile_settlement_account_object
def bank_settlement_account(settlement_method, account_name, account_number, bank_branch_ref): """ Returns a json formatted str with bank settlement account information. :param settlement_method: EFT or RTS method to transfer funds :type settlement_method: str :param account_name: The name as indicated on the bank account name :type account_name: str :param account_number: The bank account number :type account_number: str :param bank_branch_ref: An identifier identifying the destination bank branch :type bank_branch_ref: str """ # validate string arguments validation.validate_string_arguments(settlement_method, account_name, account_number, bank_branch_ref) bank_settlement_account_object = { 'settlement_method': settlement_method, 'account_name': account_name, 'account_number': account_number, 'bank_branch_ref': bank_branch_ref } return bank_settlement_account_object
def paybill_pay_recipient(paybill_name, paybill_number, paybill_account_number): """ Returns a json formatted str with the optional value of email. Checks if optional value is present, else passes values as null. :param paybill_name: Business name of the business. :type paybill_name: str :param paybill_number: Paybill business number. :type paybill_number: str :param paybill_account_number: Account number for the paybill. :type paybill_account_number: str :return: """ # validate string arguments validation.validate_string_arguments(paybill_name, paybill_number, paybill_account_number) paybill_pay_recipient_object = { 'paybill_name': paybill_name, 'paybill_number': paybill_number, 'paybill_account_number': paybill_account_number } return paybill_pay_recipient_object
def pay(destination_reference, destination_type, payment_amount, description, payment_links, payment_metadata): """ Return JSON formatted str containing information about a transfer. :param destination_reference: reference for the pay_recipient account. :type destination_reference : str :param destination_type: Differentiate between mobile and bank account type for recipient :type destination_type : str :param payment_amount: A JSON formatted str containing the currency and the amount to be transferred. :type payment_amount: str :param description: Description or purpose of payment. :type description: str :param payment_metadata: A JSON formatted str with a maximum of 5 key-value pairs. :type payment_metadata: str :param payment_links:A JSON formatted str containing a call back URL. :type payment_links: str :return: str """ # validate string arguments validation.validate_string_arguments(*destination_reference, *destination_type, *payment_amount, *description, *payment_links, *payment_metadata) payment_json_object = { "destination_reference": destination_reference, "destination_type": destination_type, "amount": payment_amount, "description": description, "metadata": payment_metadata, "_links": payment_links } return payment_json_object
def decompose(json_payload): """ Returns an instance of the K2Model class. The decomposer object is used to set values that are then accessible through python properties of the same name as the setters. Example: For the JSON object: x = { "resource": { "sender_first_name": "Tyrion", "sender_last_name": "Lanister" } } >>>from k2connect import k2_model >>>decomposer = k2_model.K2Model() >>>resource_payload_nest = payload_dictionary['event']['resource'] >>>decomposer.first_name = resource_payload_nest['sender_first_name'] test >>> print(decomposer.first_name) 'Tyrion' :param json_payload: A JSON formatted str object :type json_payload: str """ validation.validate_string_arguments(json_payload) # convert json object to python dictionary for decomposing payload_dictionary = json.loads(json_payload) # validate dictionary validation.validate_dictionary_arguments(payload_dictionary) # define result type result_type = payload_dictionary['event']['type'] # define create pay topic result_topic = payload_dictionary['topic'] # define decomposer decomposer = k2_model.K2Model() resource_payload_nest = payload_dictionary['event']['resource'] error_payload_nest = payload_dictionary['event']['errors'] links_payload_nest = payload_dictionary['_links'] # decompose all values that are similar in webhooks if result_type == BUYGOODS_TRANSACTION_RECEIVED \ or result_type == BUYGOODS_TRANSACTION_REVERSED \ or result_type == RECEIVE_PAYMENTS: decomposer.first_name = resource_payload_nest['sender_first_name'] decomposer.middle_name = resource_payload_nest['sender_middle_name'] decomposer.last_name = resource_payload_nest['sender_last_name'] decomposer.amount = resource_payload_nest['amount'] decomposer.currency = resource_payload_nest['currency'] decomposer.system = resource_payload_nest['system'] decomposer.status = resource_payload_nest['status'] decomposer.reference = resource_payload_nest['reference'] decomposer.origination_time = resource_payload_nest['origination_time'] elif result_type == B2B_TRANSACTION_RECEIVED \ or result_type == BUYGOODS_TRANSACTION_RECEIVED \ or result_type == BUYGOODS_TRANSACTION_REVERSED \ or result_topic == CREATE_PAYMENT\ or result_type == CUSTOMER_CREATED\ or result_type == MERCHANT_TO_MERCHANT_TRANSACTION_RECEIVED \ or result_type == RECEIVE_PAYMENTS\ or result_type == SETTLEMENT_TRANSFER_COMPLETED: decomposer.id = payload_dictionary['id'] decomposer.resourceId = payload_dictionary['resourceId'] # decompose all values that have similar links structures elif result_type == BUYGOODS_TRANSACTION_REVERSED \ or result_type == BUYGOODS_TRANSACTION_RECEIVED \ or result_type == SETTLEMENT_TRANSFER_COMPLETED \ or result_type == CUSTOMER_CREATED \ or result_type == B2B_TRANSACTION_RECEIVED \ or result_type == MERCHANT_TO_MERCHANT_TRANSACTION_RECEIVED: decomposer.links_self = links_payload_nest['self'] decomposer.links_resource = links_payload_nest['resource'] # decompose all values that are common to buygoods transactions elif result_type == BUYGOODS_TRANSACTION_REVERSED \ or result_type == BUYGOODS_TRANSACTION_RECEIVED: decomposer.till_number = resource_payload_nest['till_number'] decomposer.system = resource_payload_nest['system'] # decompose value specific to buygoods transaction reversed if result_type == BUYGOODS_TRANSACTION_REVERSED: decomposer.reversal_time = resource_payload_nest['reversal_time'] # decompose all values that are common to receive MPESA payments service elif result_type == RECEIVE_PAYMENTS: # receive MPESA payments decomposer.payment_result_id = payload_dictionary['payment_request_id'] decomposer.payment_result_status = payload_dictionary['status'] # receive MPESA payments errors decomposer.error_code = error_payload_nest['code'] decomposer.error_description = error_payload_nest['description'] # receive MPESA payments links decomposer.payment_request = links_payload_nest['payment_request'] # decompose all values that are common to the PAY service elif result_topic == CREATE_PAYMENT: decomposer.amount = payload_dictionary['amount']['value'] decomposer.currency = payload_dictionary['amount']['currency'] decomposer.status = payload_dictionary['status'] decomposer.reference = payload_dictionary['reference'] decomposer.origination_time = payload_dictionary['origination_time'] decomposer.destination = payload_dictionary['destination'] # decompose values common to b2b and merchant to merchant transaction received elif result_type == B2B_TRANSACTION_RECEIVED \ or result_type == MERCHANT_TO_MERCHANT_TRANSACTION_RECEIVED: decomposer.amount = resource_payload_nest['amount'] decomposer.currency = resource_payload_nest['currency'] decomposer.system = resource_payload_nest['system'] decomposer.status = resource_payload_nest['status'] decomposer.reference = resource_payload_nest['reference'] decomposer.origination_time = resource_payload_nest['origination_time'] # decompose unique to b2b transaction received elif result_type == B2B_TRANSACTION_RECEIVED: decomposer.sending_till = resource_payload_nest['sending_till'] # decompose unique to merchant to merchant transaction received elif result_type == MERCHANT_TO_MERCHANT_TRANSACTION_RECEIVED: decomposer.sending_merchant = resource_payload_nest['sending_merchant'] return decomposer
def add_pay_recipient(self, kwargs): """ Adds external entities that will be the destination of your payments. Returns a request response object < class, 'requests.models.Response'> :param kwargs: The values constitute all user input. :type kwargs: dict :return:'requests.models.Response' """ if 'access_token' not in kwargs: raise exceptions.InvalidArgumentError('Access Token not given.') if 'recipient_type' not in kwargs: raise exceptions.InvalidArgumentError('Recipient Type not given.') if 'access_token' in kwargs: bearer_token = kwargs['access_token'] if 'recipient_type' in kwargs: recipient_type = kwargs['recipient_type'] # define headers headers = dict(self._headers) validation.validate_string_arguments(bearer_token) # add bearer token headers['Authorization'] = 'Bearer ' + bearer_token # build url add_pay_url = self._build_url(url_path=ADD_PAY_PATH) if 'email' in kwargs: validation.validate_email(str(kwargs['email'])) if 'phone_number' in kwargs: validation.validate_phone_number(str(kwargs['phone_number'])) # expected parameters for bank account wallet recipient if recipient_type == BANK_ACCOUNT_RECIPIENT_TYPE: if 'account_name' not in kwargs or \ 'account_number' not in kwargs or \ 'settlement_method' not in kwargs or \ 'bank_branch_ref' not in kwargs: raise exceptions.InvalidArgumentError( 'Invalid arguments for bank account Pay recipient') # build recipient json object recipient_object = json_builder.bank_account( account_name=str(kwargs['account_name']), account_number=str(kwargs['account_number']), settlement_method=str(kwargs['settlement_method']), bank_branch_ref=str(kwargs['bank_branch_ref'])) # build bank payment recipient json object payment_recipient_object = json_builder.pay_recipient( recipient_type=recipient_type, recipient=recipient_object) # expected parameters for mobile wallet recipient # ['first_name', 'last_name', # network','phone_number','email'] elif recipient_type == MOBILE_WALLET_RECIPIENT_TYPE: if 'first_name' not in kwargs or \ 'last_name' not in kwargs or \ 'phone_number' not in kwargs or \ 'email' not in kwargs or \ 'network' not in kwargs: raise exceptions.InvalidArgumentError( 'Invalid arguments for mobile wallet Pay recipient') # create recipient json object recipient_object = json_builder.mobile_wallet( first_name=str(kwargs['first_name']), last_name=str(kwargs['last_name']), phone_number=str(kwargs['phone_number']), network=str(kwargs['network']), email=str(kwargs['email'])) # create mobile wallet recipient json object payment_recipient_object = json_builder.pay_recipient( recipient_type=recipient_type, recipient=recipient_object) elif recipient_type == TILL_RECIPIENT_TYPE: if 'till_name' not in kwargs or \ 'till_number' not in kwargs: raise exceptions.InvalidArgumentError( 'Invalid arguments for till Pay recipient') # create recipient json object recipient_object = json_builder.till_pay_recipient( till_name=str(kwargs['till_name']), till_number=str(kwargs['till_number'])) # create mobile wallet recipient json object payment_recipient_object = json_builder.pay_recipient( recipient_type=recipient_type, recipient=recipient_object) # expected parameters for mobile wallet recipient # ['till_name', 'till_number'] elif recipient_type == PAYBILL_RECIPIENT_TYPE: if 'paybill_name' not in kwargs or \ 'paybill_number' not in kwargs or \ 'paybill_account_number' not in kwargs: raise exceptions.InvalidArgumentError( 'Invalid arguments for paybill Pay recipient') # create recipient json object recipient_object = json_builder.paybill_pay_recipient( paybill_name=str(kwargs['paybill_name']), paybill_number=str(kwargs['paybill_number']), paybill_account_number=str(kwargs['paybill_account_number'])) # create mobile wallet recipient json object payment_recipient_object = json_builder.pay_recipient( recipient_type=recipient_type, recipient=recipient_object) # expected parameters for mobile wallet recipient # ['alias_name', 'till_number'] else: raise exceptions.InvalidArgumentError( 'The recipient type is not recognized by k2connect') return self._make_requests(headers=headers, method='POST', url=add_pay_url, payload=payment_recipient_object)
def send_pay(self, kwargs): """ Creates an outgoing pay to a third party. The result of the pay is provided asynchronously and posted to the callback_url provided. Returns a request response object < class, 'requests.models.Response'> :param kwargs: Provision for optional metadata with maximum of 5 key value pairs. :type kwargs: dict :return:requests.models.Response """ if 'access_token' not in kwargs: raise exceptions.InvalidArgumentError('Access Token not given.') if 'destination_reference' not in kwargs or \ 'destination_type' not in kwargs or \ 'callback_url' not in kwargs or \ 'description' not in kwargs or \ 'amount' not in kwargs: raise exceptions.InvalidArgumentError( 'Invalid arguments for creating Outgoing Pay.') if 'currency' not in kwargs: currency = 'KES' if 'metadata' not in kwargs: pay_metadata = '' # iterate through kwargs if 'access_token' in kwargs: bearer_token = kwargs['access_token'] if 'callback_url' in kwargs: callback_url = kwargs['callback_url'] if 'description' in kwargs: description = kwargs['description'] if 'currency' in kwargs: currency = 'KES' if 'metadata' in kwargs: pay_metadata = json_builder.metadata(kwargs['metadata']) # build send_pay url send_pay_url = self._build_url(SEND_PAY_PATH) # define headers headers = dict(self._headers) # check bearer token validation.validate_string_arguments(bearer_token) # add authorization to headers headers['Authorization'] = 'Bearer ' + bearer_token + '' # create amount json object pay_amount = json_builder.amount(currency=currency, value=kwargs['amount']) # create links json object pay_links = json_builder.links(callback_url=callback_url) # create payment json object pay_json = json_builder.pay(kwargs['destination_reference'], kwargs['destination_type'], pay_amount, description, pay_links, pay_metadata) return self._make_requests(url=send_pay_url, method='POST', payload=pay_json, headers=headers)
def create_payment_request(self, kwargs): """ Creates a request for the reception of payments from MPESA users. Returns a request response object < class, 'requests.models.Response'> :param kwargs: The values constitute all user input. :type kwargs: dict :return: requests.models.Response """ if 'access_token' not in kwargs: raise exceptions.InvalidArgumentError('Access Token not given.') if 'first_name' not in kwargs or \ 'last_name' not in kwargs or \ 'callback_url' not in kwargs or \ 'payment_channel' not in kwargs or \ 'phone_number' not in kwargs or \ 'till_number' not in kwargs or \ 'email' not in kwargs or \ 'amount' not in kwargs: raise exceptions.InvalidArgumentError('Invalid arguments for creating Incoming Payment Request.') if 'currency' not in kwargs: currency = 'KES' if 'metadata' not in kwargs: mpesa_payment_metadata = '' # iterate through kwargs if 'access_token' in kwargs: bearer_token = kwargs['access_token'] if 'phone_number' in kwargs: phone_number = kwargs['phone_number'] if validation.validate_phone_number(phone_number) is False: pass if 'email' in kwargs: email = kwargs['email'] validation.validate_email(email) if 'currency' in kwargs: currency = 'KES' if 'metadata' in kwargs: mpesa_payment_metadata = json_builder.metadata(kwargs['pay_metadata']) # define headers headers = dict(self._headers) # validate bearer_token validation.validate_string_arguments(bearer_token) # add bearer token headers['Authorization'] = 'Bearer ' + bearer_token + '' # build create mpesa payment request url mpesa_payment_request_url = self._build_url(CREATE_RECEIVE_MPESA_PAYMENT_PATH) # define amount JSON object mpesa_payment_request_amount = json_builder.amount(currency=currency, value=kwargs['amount']) # define links JSON object mpesa_payment_request_links = json_builder.links(callback_url=kwargs['callback_url']) # define subscriber JSON object mpesa_payment_subscriber = json_builder.subscriber(first_name=kwargs['first_name'], last_name=kwargs['last_name'], phone_number=phone_number, email=email) # define MPESA payment request JSON object mpesa_payment_request_payload = json_builder.mpesa_payment(mpesa_links=mpesa_payment_request_links, mpesa_payment_amount=mpesa_payment_request_amount, mpesa_payment_subscriber=mpesa_payment_subscriber, metadata=mpesa_payment_metadata, payment_channel=kwargs['payment_channel'], till_number=kwargs['till_number']) return self._make_requests(headers=headers, method='POST', url=mpesa_payment_request_url, payload=mpesa_payment_request_payload)