Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ Before using the SDK, users must obtain credentials from merchant portal first.
* [Get Voucher By Code](#get-voucher-by-code)
* [Get Voucher Batches](#get-voucher-batches)
* [Get Voucher Batches By Batch Key](#get-voucher-batches-by-batch-key)
* EKYC
* [Mykad Recognition](#mykad-recognition)
* [GET Mykad Result](#get-mykad-result)
* [GET EKYC Result](#get-ekyc-result)
* [Face Verification](#face-verification)

## Usage

Expand Down Expand Up @@ -370,3 +375,28 @@ result = client.voucher.getVoucherBatchByKey(accessToken, batchKey)

Detail examples can be found at [examples](https://github.com/RevenueMonster/RM-API-SDK-Python/tree/master/examples).

## EKYC

### Mykad Recognition
```python
mykad_payload = {
"notify_url": "https://aifire.com/ekyc/result",
"query_image_content": img_b64.decode('utf-8')
}
results = client.ekyc.mykad_recog(accessToken, mykad_payload)
```

### GET Mykad Result
```python
mykad_results = client.ekyc.get_mykad_results(accessToken, get_result_mykad_payload)
```

### GET EKYC Result
```python
ekyc_results = client.ekyc.get_ekyc_results(accessToken, ekyc_payload)
```

### Face Verification
```python
face_verification_results = client.ekyc.face_verification(accessToken, face_verification_payload)
```
6 changes: 3 additions & 3 deletions examples/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

configs = {
"environment": "sandbox",
"clientID": "1546849785427621041",
"clientSecret": "eNdqiTKWjbbJoSIaPEEvzGPBYrXMTWQZ",
"privateKey": "/Users/rexlow/Documents/Work/RevenueMonster/RM-API-SDK-Python/rmsdk/private.pem"
"clientID": "1604635236745642069",
"clientSecret": "TPSTBChxwEduyMdcSAzcxlhZXWNRCEJj",
"privateKey": "/workspace/rm-python-sdk/keys/private_key.pem"
}
52 changes: 52 additions & 0 deletions examples/ekyc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from rmsdk import RMSDK
from configs import configs
from pprint import pprint
import requests
import base64

def url_to_b64(img_url: str):
img_byte = requests.get(img_url).content
img_b64 = base64.b64encode(img_byte)

return img_b64

if __name__ == '__main__':
# Init client
client = RMSDK(configs=configs)
accessToken = client.accessToken

# Recognize mykad
img_url = 'https://buletinonlines.net/v7/wp-content/uploads/2016/06/Mykad-penghuni-puan-Noraini-2.jpg'
mykad_payload = {
"notify_url": "https://aifire.com/ekyc/result",
"query_image_content": url_to_b64(img_url).decode('utf-8')
}

results = client.ekyc.mykad_recog(accessToken, mykad_payload)
pprint(results)

# Get mykad results
get_result_mykad_payload = {
'id': results['item']['requestID']
}

mykad_results = client.ekyc.get_mykad_results(accessToken, get_result_mykad_payload)
pprint(mykad_results)

# Face verification
face_img_url = 'https://media.glamour.com/photos/5a425fd3b6bcee68da9f86f8/master/pass/best-face-oil.png'
img_b64 = url_to_b64(face_img_url)

face_verification_payload = {
"query_image_content_1": img_b64.decode('utf-8'),
"query_image_content_2": img_b64.decode('utf-8'),
}
face_verification_results = client.ekyc.face_verification(accessToken, face_verification_payload)
pprint(face_verification_results)

# Get EKYC Results
# ekyc_payload = {
# "id": "62201d48a694817dede84b35"
# }
# ekyc_results = client.ekyc.get_ekyc_results(accessToken, ekyc_payload)
# pprint(ekyc_results)
2 changes: 1 addition & 1 deletion examples/signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@
requestUrl="https://sb-open.revenuemonster.my/v3/payment/quickpay",
signType="sha256",
timestamp="1546931187.8109288",
privateKeyDest="/Users/rexlow/Documents/Work/RevenueMonster/RM-API-SDK-Python/rmsdk/private.pem")
privateKeyDest="/workspace/rm-python-sdk/keys/private_key.pem")

print(signature)
6 changes: 4 additions & 2 deletions rmsdk/RMSDK.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
Store,
Transaction,
User,
Voucher
Voucher,
EKYC
)

class RMSDK(object):
Expand All @@ -28,4 +29,5 @@ def __init__(self, configs={}):
self.store = Store(configs)
self.transaction = Transaction(configs)
self.user = User(configs)
self.voucher = Voucher(configs)
self.voucher = Voucher(configs)
self.ekyc = EKYC(configs)
1 change: 1 addition & 0 deletions rmsdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@
from .payment import QuickPay, Transaction
from .loyalty import Loyalty
from .voucher import Voucher
from .ekyc import EKYC
from .RMSDK import RMSDK
96 changes: 96 additions & 0 deletions rmsdk/ekyc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import json
from .model import RMSDKModel
from .request import Request

class EKYC(RMSDKModel):
def __init__(self, configs):
super(EKYC, self).__init__(configs)
self.defaults = {
"environment": configs["environment"],
"privateKey": configs["privateKey"],
}

for (param, default) in self.defaults.items():
setattr(self, param, configs.get(param, default))

self.payload = {
"service": "ekyc",
"version": "v1",
}

def mykad_recog(self, accessToken: str, data: dict) -> dict:
"""
Function to make http request to get recognize mykad

args:
accessToken (str): Access Token to allow open api to get user
data (dict): Data to send to open api server

returns:
dict: dict containing only id for mykad recog result (require to parse the results via different route)
"""
request = Request(environment=self.defaults['environment'], endpoint='v3/service')
self.payload['function'] = 'id-mykad'
self.payload['request'] = data

headers, data = self.getHeadersAndData(accessToken=accessToken, data=self.payload, requestUrl=request.baseUrl)
response = request.doPost(headers=headers, data=data)
return response

def face_verification(self, accessToken: str, data: dict) -> dict:
"""
Funtion to get the similarity between two faces

args:
accessToken (str): Access Token to allow open api to get user
data (dict): Data to send to open api server

returns:
dict: Results if the two faces are similar or not
"""
request = Request(environment=self.defaults['environment'], endpoint='v3/service')
self.payload['function'] = 'face-compare'
self.payload['request'] = data

headers, data = self.getHeadersAndData(accessToken=accessToken, data=self.payload, requestUrl=request.baseUrl)

response = request.doPost(headers=headers, data=data)
return response

def get_mykad_results(self, accessToken: str, data: dict) -> dict:
"""
Function to get the results from the recognized mykad

args:
accessToken (str): Access Token to allow open api to get user
data (dict): Data to send to open api server

returns:
dict: Results containing the recognize mykad
"""
self.payload['function'] = "get-mykad-result"
self.payload['request'] = data
request = Request(environment=self.defaults['environment'], endpoint='v3/service')
headers, data = self.getHeadersAndData(accessToken=accessToken, data=self.payload, requestUrl=request.baseUrl)

response = request.doPost(headers=headers, data=data)
return response

def get_ekyc_results(self, accessToken: str, data: dict) -> dict:
"""
Function to get the end to end ekyc results

args:
accessToken (str): Access Token to allow open api to get user
data (dict): Data to send to open api server

returns:
dict: Results containing the end to end including face and mykad results
"""
request = Request(environment=self.defaults['environment'], endpoint='v3/service')
self.payload['function'] = "get-ekyc-result"
self.payload['request'] = data
headers, data = self.getHeadersAndData(accessToken=accessToken, data=self.payload, requestUrl=request.baseUrl)

response = request.doPost(headers=headers, data=data)
return response
2 changes: 1 addition & 1 deletion rmsdk/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def getSignature(self, data, method, nonceStr, requestUrl, timestamp):

def getHeadersAndData(self, accessToken, requestUrl, method="post", data=None):
nonceStr = getNonce()
timestamp = str(time())
timestamp = str(int(time()))

if data is not None:
data = json.dumps(orderDict(data), separators=(',', ':'))
Expand Down
48 changes: 48 additions & 0 deletions tests/test_rmsdk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import unittest
import base64
import requests
from rmsdk import RMSDK
from examples.configs import configs

class TestEKYCSDK(unittest.TestCase):
def setUp(self):
self.client = RMSDK(configs=configs)
self.accessToken = self.client.accessToken

def to_b64(self, img_url: str):
img_byte = requests.get(img_url).content
img_b64 = base64.b64encode(img_byte)

return img_b64

def test_mykad_recog(self):
img_url = 'https://buletinonlines.net/v7/wp-content/uploads/2016/06/Mykad-penghuni-puan-Noraini-2.jpg'
img_b64 = self.to_b64(img_url)

mykad_payload = {
"notify_url": "https://aifire.com/ekyc/result",
"query_image_content": img_b64.decode('utf-8')
}

results = self.client.ekyc.mykad_recog(self.accessToken, mykad_payload)
get_result_mykad_payload = {
'id': results['item']['requestID']
}

mykad_results = self.client.ekyc.get_mykad_results(self.accessToken, get_result_mykad_payload)
self.assertIn('item', mykad_results)

def test_face_verfication(self):
face_img_url = 'https://media.glamour.com/photos/5a425fd3b6bcee68da9f86f8/master/pass/best-face-oil.png'
img_b64 = self.to_b64(face_img_url)

face_verification_payload = {
"query_image_content_1": img_b64.decode('utf-8'),
"query_image_content_2": img_b64.decode('utf-8')
}
face_verification_results = self.client.ekyc.face_verification(self.accessToken, face_verification_payload)
self.assertIn('item', face_verification_results)

self.assertIn('similarity', face_verification_results['item'])
self.assertEqual(face_verification_results['item']['isSamePerson'], True)