JonTheWong Posted November 5, 2019 Share Posted November 5, 2019 Hello, I'm working on a python script and i'd like to insert customfields on the updateclient call. This is a json of tblcustomfields {"id":"2","type":"client","relid":"0","fieldname":"status","fieldtype":"dropdown","description":"","fieldoptions":"notVerified,verified","regexpr":"","adminonly":"on","required":"","showorder":"","showinvoice":"","sortorder":"0","created_at":"0000-00-00 00:00:00","updated_at":"0000-00-00 00:00:00"}, tblcustomfieldsvalues {"id":"5","fieldid":"2","relid":"297","value":"verified","created_at":"2019-11-05 04:38:50","updated_at":"2019-11-05 04:38:50"}, {"id":"6","fieldid":"3","relid":"297","value":"","created_at":"2019-11-05 04:38:50","updated_at":"2019-11-05 04:38:50"}, {"id":"7","fieldid":"4","relid":"297","value":"","created_at":"2019-11-05 04:38:50","updated_at":"2019-11-05 04:38:50"}, {"id":"8","fieldid":"6","relid":"297","value":"","created_at":"2019-11-05 04:38:50","updated_at":"2019-11-05 04:38:50"} Now when it comes to pushing the data, the documentation isn't clear. All i'm seeing is; customfields|string|Base64 encoded serialized array of custom field values|Optional Based on web searching, its not getting clearer. Here is a snipped of my last code. cstatus = { "fieldid": "2", "value": "verified" } encoded = base64.b64encode(b'cstatus') with requests.Session() as session_whmcs_bounces: session_whmcs_bounces.headers.update(whmcs_auth) whmcs_bounces_payload = { 'identifier': whmcs_ident, 'secret': whmcs_secret, 'responsetype': whmcs_response, 'action': "UpdateClient", 'clientemail': email, 'status': "Inactive", 'marketingoptin': 0, 'notes': '--- Bounces ---\nCreated: %s\nStatus: %s\nReason: %s\n---Bounces---' % (timeconvert,status,reason), 'customfields': encoded } i tried using the json.dumps/json.loads techniques to serialize the data, but in my mind i don't have to since the data is already serialized, i just have to encode it. I also tried variations, as in just the ID and value { "2": "verified" } / { "id": "2", "value": "verified" } and different combinations. Been at it for a few hours and can't seem to find much information. Ideally i'd like to update multiple sections based on the json reply. The flow i'm trying to achieve is this; Receive client information from datasource. { "email": "example@domain.tld", "type": "prospect", "status": "verified", "firstName": "Jon", "lastName": "Wong", "position": "Senior Linux Administrator", "sourcePage": "https:\/\/www.linkedin.com\/in\/jonthewong" } Add it or Update it into WHMCS Use extra fields as customfields. In this case, type/status/position/sourcepage The python code shown is for a separate part of the project, but the customfields base64,serialization still apply. If anyone has any experience or suggestions i'd appreciate it. Thank you. On a side note, I'm using Python 3.7 + requests/time/json/base64/getpass I'm open to adding other libs, but ideally i'd prefer using the ones i already have build for this env. 0 Quote Link to comment Share on other sites More sharing options...
mnakhaev Posted May 15, 2020 Share Posted May 15, 2020 Hello, Any update on this issue? Faced with the same problem - not clear how to set `Base64 encoded serialized array of custom field values` from python 0 Quote Link to comment Share on other sites More sharing options...
MeShootMeMiss Posted June 17, 2020 Share Posted June 17, 2020 Right, so I am doing some python automatisation myself and was stuck on this problem for half a day, so if anyone needs info on how to send customfields param to WHMCS api with python here it is. This is a simple script to AddOrder with some custom fields in it: import requests import base64 import phpserialize # Setting up default settings identifier = "yourIdentifier" secret = "yourSecret" url = "yourAPIurl" # Making the customfields string customfieldsVALUE = base64.b64encode(phpserialize.dumps({'fieldID':'fieldVALUE', 'fieldID2':'fieldVALUE2'})) # Assigning params to a dict params = { 'identifier': identifier, 'secret': secret, 'action': "AddOrder", 'responsetype': "json", 'clientid': 'yourClientID', 'paymentmethod': 'yourPaymentMethod', 'pid': 'yourPuschaseID', 'domain': 'yourDomain', 'billingcycle': 'yourBillingCycle', 'customfields': customfieldsVALUE #this is the string that i setup above } # sending the request r = requests.post(url, params=params) answer = r.text # this returns a big string, you need to convert it into json if you want to use the answer in any way print(answer) Main thing to understand is that the API is asking for base64 encoded serialized array(or in python case a dictionary), and it wants us to use the php serialize, so to get around that we have to import custom lib(i used phpserialize), that can serialize data in php way, and use it on our array of customfield key and value pairs before we encode it with base64: customfieldsVALUE = base64.b64encode(phpserialize.dumps({'fieldID':'fieldVALUE', 'fieldID2':'fieldVALUE2'})) 2 Quote Link to comment Share on other sites More sharing options...
JonTheWong Posted June 23, 2020 Author Share Posted June 23, 2020 (edited) customfieldsVALUE = base64.b64encode(phpserialize.dumps({'fieldID':'fieldVALUE', 'fieldID2':'fieldVALUE2'})) Just perfect, working for me on Python 3.7 Thanks a bunch i appreciate the feedback. If anyone is having issues finding the fieldID; its in 'tblcustomfields' in the database. Nothing special if its a dropdown, link or text fieldtype. Haven't testing it with any validation but i assume thats frontend vs a direct api entry. Edited June 23, 2020 by jwong 0 Quote Link to comment Share on other sites More sharing options...
pentom12 Posted September 23, 2020 Share Posted September 23, 2020 Are you sure this is working? cant make it work. I use the product ids from the my db(15,16,38) and its still not working. can you give a request example please? 0 Quote Link to comment Share on other sites More sharing options...
JonTheWong Posted September 28, 2020 Author Share Posted September 28, 2020 (edited) @pentom12 This is what i have; serializedcustomfields = base64.b64encode(phpserialize.dumps({cidStatus: 'verified', cidType: 'prospect', cidTitle: title, cidDomain: domain, cidSource: sourcepage, cidResults: size, cidWebmail: webmail})) params = { 'identifier': identifier, 'secret': secret, 'responsetype': 'JSON', 'action': 'AddClient', 'currency': 1, 'groupid': groupid, 'notes': 'import', 'marketingoptin': True, 'noemail': True, 'skipvalidation': True, 'customfields': serializedcustomfields, 'companyname': companyname, 'phonenumber': phonenumber, 'address1': address1, 'city': city, 'state': state, 'country': country, 'postcode': postcode, 'email': email, } res = requests.post(posturi, data=params, verify=True, timeout=120) It looks like your trying to add custom fields to products. What "action" are you trying to add serialized custom fields too? I'm using it in the "AddClient" request. Verify that your method supports custom fields. good luck Edited September 28, 2020 by JonTheWong syntax highlight 0 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.